diff --git a/credentials/apps/badges/admin.py b/credentials/apps/badges/admin.py
index fee35b5141..bdf43756b5 100644
--- a/credentials/apps/badges/admin.py
+++ b/credentials/apps/badges/admin.py
@@ -47,10 +47,10 @@ class BadgeRequirementInline(admin.TabularInline):
"event_type",
"rules",
"description",
- "group",
+ "blend",
)
readonly_fields = ("rules",)
- ordering = ("group",)
+ ordering = ("blend",)
form = BadgeRequirementForm
formset = BadgeRequirementFormSet
@@ -194,7 +194,7 @@ def get_fields(self, request, obj=None):
return fields
def get_readonly_fields(self, request, obj=None):
- readonly_fields = super().get_readonly_fields(request, obj)
+ readonly_fields = list(super().get_readonly_fields(request, obj))
if not obj:
return readonly_fields
@@ -247,7 +247,7 @@ class CredlyBadgeTemplateAdmin(admin.ModelAdmin):
"description": _(
"""
WARNING: avoid configuration updates on activated badges.
- Active badge templates are continuously processed and learners may already have partial progress on them.
+ Active badge templates are continuously processed and learners may already have progress on them.
Any changes in badge template requirements (including data rules) will affect learners' experience!
"""
),
@@ -318,10 +318,10 @@ def image(self, obj):
image.short_description = _("icon")
- def save_model(self, request, obj, form, change): # pylint: disable=unused-argument
+ def save_model(self, request, obj, form, change):
pass
- def save_formset(self, request, form, formset, change): # pylint: disable=unused-argument
+ def save_formset(self, request, form, formset, change):
"""
Check if template is active and has requirements.
"""
@@ -331,7 +331,7 @@ def save_formset(self, request, form, formset, change): # pylint: disable=unuse
messages.set_level(request, messages.ERROR)
messages.error(request, _("Active badge template must have at least one requirement."))
return HttpResponseRedirect(request.path)
- form.instance.save()
+ return form.instance.save()
class DataRulePenaltyInline(admin.TabularInline):
@@ -368,14 +368,14 @@ class BadgeRequirementAdmin(admin.ModelAdmin):
"template",
"event_type",
"template_link",
- "group",
+ "blend",
]
fields = [
"template_link",
"event_type",
"description",
- "group",
+ "blend",
]
def has_add_permission(self, request):
@@ -455,15 +455,6 @@ def formfield_for_manytomany(self, db_field, request, **kwargs):
kwargs["queryset"] = BadgeRequirement.objects.filter(template_id=template_id)
return super().formfield_for_manytomany(db_field, request, **kwargs)
- def template_link(self, instance):
- """
- Interactive link to parent (badge template).
- """
- url = reverse("admin:badges_credlybadgetemplate_change", args=[instance.template.pk])
- return format_html('{}', url, instance.template)
-
- template_link.short_description = _("badge template")
-
def response_change(self, request, obj):
if "_save" in request.POST:
return HttpResponseRedirect(reverse("admin:badges_credlybadgetemplate_change", args=[obj.template.pk]))
diff --git a/credentials/apps/badges/admin_forms.py b/credentials/apps/badges/admin_forms.py
index a27d1b891f..89b70be1d0 100644
--- a/credentials/apps/badges/admin_forms.py
+++ b/credentials/apps/badges/admin_forms.py
@@ -50,7 +50,7 @@ def clean(self):
api_key = settings.BADGES_CONFIG["credly"]["ORGANIZATIONS"][str(uuid)]
credly_api_client = CredlyAPIClient(uuid, api_key)
- self._ensure_organization_exists(credly_api_client)
+ self.ensure_organization_exists(credly_api_client)
return cleaned_data
@@ -64,7 +64,7 @@ def save(self, commit=True):
return instance
- def _ensure_organization_exists(self, api_client):
+ def ensure_organization_exists(self, api_client):
"""
Try to fetch organization data by the configured Credly Organization ID.
"""
@@ -93,7 +93,7 @@ def clean(self):
requirements = cleaned_data.get("requirements")
if requirements and not all(
- [requirement.template.id == cleaned_data.get("template").id for requirement in requirements]
+ requirement.template.id == cleaned_data.get("template").id for requirement in requirements
):
raise forms.ValidationError(_("All requirements must belong to the same template."))
return cleaned_data
@@ -143,7 +143,8 @@ def clean(self):
return cleaned_data
-class DataRuleFormSet(ParentMixin, forms.BaseInlineFormSet): ...
+class DataRuleFormSet(ParentMixin, forms.BaseInlineFormSet):
+ pass
class DataRuleForm(DataRuleExtensionsMixin, forms.ModelForm):
@@ -158,7 +159,8 @@ class Meta:
data_path = forms.ChoiceField()
-class BadgeRequirementFormSet(ParentMixin, forms.BaseInlineFormSet): ...
+class BadgeRequirementFormSet(ParentMixin, forms.BaseInlineFormSet):
+ pass
class BadgeRequirementForm(forms.ModelForm):
@@ -166,17 +168,18 @@ class Meta:
model = BadgeRequirement
fields = "__all__"
- group = forms.ChoiceField()
+ blend = forms.ChoiceField()
def __init__(self, *args, parent_instance=None, **kwargs):
self.template = parent_instance
super().__init__(*args, **kwargs)
- self.fields["group"].choices = Choices(*[(chr(i), chr(i)) for i in range(65, 91)])
- self.fields["group"].initial = chr(65 + self.template.requirements.count())
+ self.fields["blend"].choices = Choices(*[(chr(i), chr(i)) for i in range(65, 91)])
+ self.fields["blend"].initial = chr(65 + self.template.requirements.count())
-class PenaltyDataRuleFormSet(ParentMixin, forms.BaseInlineFormSet): ...
+class PenaltyDataRuleFormSet(ParentMixin, forms.BaseInlineFormSet):
+ pass
class PenaltyDataRuleForm(DataRuleExtensionsMixin, forms.ModelForm):
diff --git a/credentials/apps/badges/apps.py b/credentials/apps/badges/apps.py
index 18c9da60eb..1426149e9f 100644
--- a/credentials/apps/badges/apps.py
+++ b/credentials/apps/badges/apps.py
@@ -1,6 +1,6 @@
from django.apps import AppConfig
-from .toggles import check_badges_enabled
+from credentials.apps.badges.toggles import check_badges_enabled
class BadgesAppConfig(AppConfig):
@@ -8,6 +8,8 @@ class BadgesAppConfig(AppConfig):
Extended application config with additional Badges-specific logic.
"""
+ plugin_label = "badges"
+
@property
def verbose_name(self):
return f"Badges: {self.plugin_label}"
@@ -29,9 +31,11 @@ def ready(self):
Performs initial registrations for checks, signals, etc.
"""
- from . import signals # pylint: disable=unused-import,import-outside-toplevel
- from .checks import badges_checks # pylint: disable=unused-import,import-outside-toplevel
- from .signals.handlers import listen_to_badging_events
+ from credentials.apps.badges import signals # pylint: disable=unused-import,import-outside-toplevel
+ from credentials.apps.badges.checks import ( # pylint: disable=unused-import,import-outside-toplevel
+ badges_checks,
+ )
+ from credentials.apps.badges.signals.handlers import listen_to_badging_events # pylint: import-outside-toplevel
listen_to_badging_events()
diff --git a/credentials/apps/badges/credly/api_client.py b/credentials/apps/badges/credly/api_client.py
index 23f805de01..793f4c85ea 100644
--- a/credentials/apps/badges/credly/api_client.py
+++ b/credentials/apps/badges/credly/api_client.py
@@ -70,7 +70,7 @@ def perform_request(self, method, url_suffix, data=None):
"""
url = urljoin(self.base_api_url, url_suffix)
logger.debug(f"Credly API: {method.upper()} {url}")
- response = requests.request(method.upper(), url, headers=self._get_headers(), json=data)
+ response = requests.request(method.upper(), url, headers=self._get_headers(), json=data, timeout=10)
self._raise_for_error(response)
return response.json()
diff --git a/credentials/apps/badges/credly/exceptions.py b/credentials/apps/badges/credly/exceptions.py
index 6752803f69..7fbb2a4374 100644
--- a/credentials/apps/badges/credly/exceptions.py
+++ b/credentials/apps/badges/credly/exceptions.py
@@ -10,12 +10,8 @@ class CredlyError(BadgesError):
Credly backend generic error.
"""
- pass
-
class CredlyAPIError(CredlyError):
"""
Credly API errors.
"""
-
- pass
diff --git a/credentials/apps/badges/exceptions.py b/credentials/apps/badges/exceptions.py
index c5950e24f7..fea8e2632b 100644
--- a/credentials/apps/badges/exceptions.py
+++ b/credentials/apps/badges/exceptions.py
@@ -8,20 +8,14 @@ class BadgesError(Exception):
Badges generic exception.
"""
- pass
-
class BadgesProcessingError(BadgesError):
"""
Exception raised for errors that occur during badge processing.
"""
- pass
-
class StopEventProcessing(BadgesProcessingError):
"""
Exception raised to stop processing an event due to a specific condition.
"""
-
- pass
diff --git a/credentials/apps/badges/issuers.py b/credentials/apps/badges/issuers.py
index d11f74ed0d..fe46de619c 100644
--- a/credentials/apps/badges/issuers.py
+++ b/credentials/apps/badges/issuers.py
@@ -36,7 +36,7 @@ def issue_credential(
attributes=None,
date_override=None,
request=None,
- lms_user_id=None, # pylint: disable=unused-argument
+ lms_user_id=None,
):
"""
Issue a credential to the user.
diff --git a/credentials/apps/badges/management/commands/sync_organization_badge_templates.py b/credentials/apps/badges/management/commands/sync_organization_badge_templates.py
index 29da77e488..b55e968abb 100644
--- a/credentials/apps/badges/management/commands/sync_organization_badge_templates.py
+++ b/credentials/apps/badges/management/commands/sync_organization_badge_templates.py
@@ -21,8 +21,11 @@ def handle(self, *args, **options):
Sync badge templates for a specific organization or all organizations.
Usage:
- ./manage.py sync_organization_badge_templates --site_id 1
- ./manage.py sync_organization_badge_templates --site_id 1 --organization_id c117c179-81b1-4f7e-a3a1-e6ae30568c13
+ site_id=1
+ org_id=c117c179-81b1-4f7e-a3a1-e6ae30568c13
+
+ ./manage.py sync_organization_badge_templates --site_id $site_id
+ ./manage.py sync_organization_badge_templates --site_id $site_id --organization_id $org_id
"""
DEFAULT_SITE_ID = 1
organizations_to_sync = []
@@ -40,7 +43,8 @@ def handle(self, *args, **options):
else:
organizations_to_sync = CredlyOrganization.get_all_organization_ids()
logger.info(
- f"Organization ID wasn't provided: syncing badge templates for all organizations - {organizations_to_sync}"
+ "Organization ID wasn't provided: syncing badge templates for all organizations - "
+ f"{organizations_to_sync}",
)
for organization_id in organizations_to_sync:
diff --git a/credentials/apps/badges/migrations/0022_rename_group_fulfillment_blend_and_more.py b/credentials/apps/badges/migrations/0022_rename_group_fulfillment_blend_and_more.py
new file mode 100644
index 0000000000..fc193b3192
--- /dev/null
+++ b/credentials/apps/badges/migrations/0022_rename_group_fulfillment_blend_and_more.py
@@ -0,0 +1,64 @@
+# Generated by Django 4.1 on 2024-05-31 13:46
+
+from django.db import migrations, models
+import model_utils.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("badges", "0021_alter_credlyorganization_api_key"),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name="fulfillment",
+ old_name="group",
+ new_name="blend",
+ ),
+ migrations.RemoveField(
+ model_name="badgerequirement",
+ name="group",
+ ),
+ migrations.AddField(
+ model_name="badgerequirement",
+ name="blend",
+ field=models.CharField(
+ blank=True,
+ help_text="Optional. Group requirements together using the same Group ID for interchangeable (OR processing logic).",
+ max_length=255,
+ null=True,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="badgetemplate",
+ name="state",
+ field=model_utils.fields.StatusField(
+ choices=[("draft", "draft"), ("active", "active"), ("archived", "archived")],
+ default="draft",
+ help_text="Credly badge template state (auto-managed).",
+ max_length=100,
+ no_check_for_status=True,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="credlybadge",
+ name="state",
+ field=model_utils.fields.StatusField(
+ choices=[
+ ("created", "created"),
+ ("no_response", "no_response"),
+ ("error", "error"),
+ ("pending", "pending"),
+ ("accepted", "accepted"),
+ ("rejected", "rejected"),
+ ("revoked", "revoked"),
+ ("expired", "expired"),
+ ],
+ default="created",
+ help_text="Credly badge issuing state",
+ max_length=100,
+ no_check_for_status=True,
+ ),
+ ),
+ ]
diff --git a/credentials/apps/badges/models.py b/credentials/apps/badges/models.py
index 0f8b21aeab..b2f028de64 100644
--- a/credentials/apps/badges/models.py
+++ b/credentials/apps/badges/models.py
@@ -36,7 +36,9 @@ class CredlyOrganization(TimeStampedModel):
uuid = models.UUIDField(unique=True, help_text=_("Put your Credly Organization ID here."))
api_key = models.CharField(
- max_length=255, help_text=_("Credly API shared secret for Credly Organization."), blank=True
+ max_length=255,
+ help_text=_("Credly API shared secret for Credly Organization."),
+ blank=True,
)
name = models.CharField(
max_length=255,
@@ -104,7 +106,7 @@ def save(self, *args, **kwargs):
@property
def groups(self):
- return self.requirements.values_list("group", flat=True).distinct()
+ return self.requirements.values_list("blend", flat=True).distinct()
@classmethod
def by_uuid(cls, template_uuid):
@@ -173,17 +175,19 @@ class BadgeRequirement(models.Model):
max_length=255,
choices=EVENT_TYPES,
help_text=_(
- 'Public signal type. Available events are configured in "BADGES_CONFIG" setting. The crucial aspect for event to carry UserData in its payload.'
+ 'Public signal type. Available events are configured in "BADGES_CONFIG" setting. '
+ "The crucial aspect for event to carry UserData in its payload."
),
)
description = models.TextField(null=True, blank=True, help_text=_("Provide more details if needed."))
- group = models.CharField(
+ blend = models.CharField(
max_length=255,
null=True,
blank=True,
help_text=_(
- "Optional. Put requirements into the same arbitrary Group ID to make them interchangeable (OR processing logic applies)."
+ "Optional. Group requirements together using the same Group ID for interchangeable (OR processing logic)."
),
+ verbose_name=_("group"),
)
def __str__(self):
@@ -200,7 +204,7 @@ def fulfill(self, username: str):
"""
template_id = self.template.id
progress = BadgeProgress.for_user(username=username, template_id=template_id)
- fulfillment, created = Fulfillment.objects.get_or_create(progress=progress, requirement=self, group=self.group)
+ fulfillment, created = Fulfillment.objects.get_or_create(progress=progress, requirement=self, blend=self.blend)
if created:
notify_requirement_fulfilled(
@@ -248,7 +252,7 @@ def is_group_fulfilled(cls, *, group: str, template: BadgeTemplate, username: st
"""
progress = BadgeProgress.for_user(username=username, template_id=template.id)
- requirements = cls.objects.filter(template=template, group=group)
+ requirements = cls.objects.filter(template=template, blend=group)
fulfilled_requirements = requirements.filter(fulfillments__progress=progress).count()
return fulfilled_requirements > 0
@@ -532,7 +536,13 @@ class Fulfillment(models.Model):
null=True,
related_name="fulfillments",
)
- group = models.CharField(max_length=255, null=True, blank=True, help_text=_("Group ID for the requirement."))
+ blend = models.CharField(
+ max_length=255,
+ null=True,
+ blank=True,
+ help_text=_("Group ID for the requirement."),
+ verbose_name=_("group"),
+ )
class CredlyBadge(UserCredential):
diff --git a/credentials/apps/badges/processing/generic.py b/credentials/apps/badges/processing/generic.py
index 8f54808c16..3ac0839841 100644
--- a/credentials/apps/badges/processing/generic.py
+++ b/credentials/apps/badges/processing/generic.py
@@ -65,7 +65,10 @@ def identify_user(*, event_type, event_payload):
user_data = get_user_data(event_payload)
if not user_data:
- message = f"User data cannot be found (got: {user_data}): {event_payload}. Does event {event_type} include user data at all?"
+ message = (
+ f"User data cannot be found (got: {user_data}): {event_payload}. "
+ f"Does event {event_type} include user data at all?"
+ )
raise BadgesProcessingError(message)
user, __ = get_or_create_user_from_event_data(user_data)
diff --git a/credentials/apps/badges/signals/handlers.py b/credentials/apps/badges/signals/handlers.py
index 27e1ab5fc2..2044e08494 100644
--- a/credentials/apps/badges/signals/handlers.py
+++ b/credentials/apps/badges/signals/handlers.py
@@ -36,7 +36,7 @@ def listen_to_badging_events():
signal.connect(handle_badging_event, dispatch_uid=event_type)
-def handle_badging_event(sender, signal, **kwargs):
+def handle_badging_event(sender, signal, **kwargs): # pylint: disable=unused-argument
"""
Generic handler for incoming from the Event bus public signals.
"""
@@ -47,7 +47,7 @@ def handle_badging_event(sender, signal, **kwargs):
@receiver(BADGE_REQUIREMENT_FULFILLED)
-def handle_requirement_fulfilled(sender, username, **kwargs): # pylint: disable=unused-argument
+def handle_requirement_fulfilled(sender, username, **kwargs):
"""
On user's Badge progression (completion).
"""
@@ -55,7 +55,7 @@ def handle_requirement_fulfilled(sender, username, **kwargs): # pylint: disable
@receiver(BADGE_REQUIREMENT_REGRESSED)
-def handle_requirement_regressed(sender, username, **kwargs): # pylint: disable=unused-argument
+def handle_requirement_regressed(sender, username, **kwargs):
"""
On user's Badge regression (incompletion).
"""
diff --git a/credentials/apps/badges/signals/signals.py b/credentials/apps/badges/signals/signals.py
index c7faf9eaef..db224ff549 100644
--- a/credentials/apps/badges/signals/signals.py
+++ b/credentials/apps/badges/signals/signals.py
@@ -71,7 +71,7 @@ def notify_progress_incomplete(sender, username, badge_template_id):
)
-def notify_badge_awarded(user_credential): # pylint: disable=unused-argument
+def notify_badge_awarded(user_credential):
"""
Emits a public signal about the badge template completion for user.
@@ -82,7 +82,7 @@ def notify_badge_awarded(user_credential): # pylint: disable=unused-argument
BADGE_AWARDED.send_event(badge=user_credential.as_badge_data())
-def notify_badge_revoked(user_credential): # pylint: disable=unused-argument
+def notify_badge_revoked(user_credential):
"""
Emit public event about badge template regression.
diff --git a/credentials/apps/badges/tests/test_admin_forms.py b/credentials/apps/badges/tests/test_admin_forms.py
index 2c5fede194..6a5914e936 100644
--- a/credentials/apps/badges/tests/test_admin_forms.py
+++ b/credentials/apps/badges/tests/test_admin_forms.py
@@ -76,9 +76,7 @@ def test_clean_requirements_different_template(self):
with self.assertRaises(forms.ValidationError) as cm:
form.clean()
- self.assertEqual(
- str(cm.exception), "['All requirements must belong to the same template.']"
- )
+ self.assertEqual(str(cm.exception), "['All requirements must belong to the same template.']")
@override_settings(BADGES_CONFIG={"credly": {"ORGANIZATIONS": {}}})
def test_clean(self):
@@ -93,9 +91,7 @@ def test_clean(self):
) as mock_get_orgs:
mock_get_orgs.return_value = {}
- with patch(
- "credentials.apps.badges.admin_forms.CredlyAPIClient"
- ) as mock_client:
+ with patch("credentials.apps.badges.admin_forms.CredlyAPIClient") as mock_client:
mock_client.return_value = MagicMock()
form.clean()
@@ -103,9 +99,7 @@ def test_clean(self):
mock_get_orgs.assert_called_once()
mock_client.assert_called_once_with("test_uuid", "test_api_key")
- @override_settings(
- BADGES_CONFIG={"credly": {"ORGANIZATIONS": {"test_uuid": "test_api_key"}}}
- )
+ @override_settings(BADGES_CONFIG={"credly": {"ORGANIZATIONS": {"test_uuid": "test_api_key"}}})
def test_clean_with_configured_organization(self):
form = CredlyOrganizationAdminForm()
form.cleaned_data = {
@@ -118,9 +112,7 @@ def test_clean_with_configured_organization(self):
) as mock_get_orgs:
mock_get_orgs.return_value = {"test_uuid": "test_org"}
- with patch(
- "credentials.apps.badges.admin_forms.CredlyAPIClient"
- ) as mock_client:
+ with patch("credentials.apps.badges.admin_forms.CredlyAPIClient") as mock_client:
mock_client.return_value = MagicMock()
form.clean()
@@ -143,9 +135,7 @@ def test_clean_with_invalid_organization(self):
with self.assertRaises(forms.ValidationError) as cm:
form.clean()
- self.assertIn(
- "You specified an invalid authorization token.", str(cm.exception)
- )
+ self.assertIn("You specified an invalid authorization token.", str(cm.exception))
def test_clean_cannot_provide_api_key_for_configured_organization(self):
form = CredlyOrganizationAdminForm()
@@ -172,7 +162,7 @@ def test_ensure_organization_exists(self):
api_client = MagicMock()
api_client.fetch_organization.return_value = {"data": {"org_id": "test_org_id"}}
- form._ensure_organization_exists(api_client)
+ form.ensure_organization_exists(api_client)
api_client.fetch_organization.assert_called_once()
self.assertEqual(form.api_data, {"org_id": "test_org_id"})
@@ -183,15 +173,14 @@ def test_ensure_organization_exists_with_error(self):
api_client.fetch_organization.side_effect = CredlyAPIError("API Error")
with self.assertRaises(forms.ValidationError) as cm:
- form._ensure_organization_exists(api_client)
+ form.ensure_organization_exists(api_client)
api_client.fetch_organization.assert_called_once()
self.assertEqual(str(cm.exception), "['API Error']")
class TestParentMixin(ParentMixin):
- def get_form_kwargs(self, index):
- return super().get_form_kwargs(index)
+ pass
class ParentMixinTestCase(TestCase):
diff --git a/credentials/apps/badges/tests/test_api_client.py b/credentials/apps/badges/tests/test_api_client.py
index 3da2806ea5..1d9c29a32a 100644
--- a/credentials/apps/badges/tests/test_api_client.py
+++ b/credentials/apps/badges/tests/test_api_client.py
@@ -4,10 +4,9 @@
from django.test import TestCase
from faker import Faker
from openedx_events.learning.data import BadgeData, BadgeTemplateData, UserData, UserPersonalData
-from requests.models import Response
from credentials.apps.badges.credly.api_client import CredlyAPIClient
-from credentials.apps.badges.credly.exceptions import CredlyAPIError, CredlyError
+from credentials.apps.badges.credly.exceptions import CredlyError
from credentials.apps.badges.models import CredlyOrganization
@@ -20,9 +19,7 @@ def setUp(self):
user=UserData(
id=1,
is_active=True,
- pii=UserPersonalData(
- username="test_user", email="test_email@mail.com", name="Test User"
- ),
+ pii=UserPersonalData(username="test_user", email="test_email@mail.com", name="Test User"),
),
template=BadgeTemplateData(
uuid=fake.uuid4(),
@@ -34,21 +31,17 @@ def setUp(self):
)
def test_get_organization_nonexistent(self):
- with mock.patch(
- "credentials.apps.badges.credly.api_client.CredlyOrganization.objects.get"
- ) as mock_get:
+ with mock.patch("credentials.apps.badges.credly.api_client.CredlyOrganization.objects.get") as mock_get:
mock_get.side_effect = CredlyOrganization.DoesNotExist
with self.assertRaises(CredlyError) as cm:
- self.api_client._get_organization("nonexistent_organization_id")
+ CredlyAPIClient("nonexistent_organization_id")
self.assertEqual(
str(cm.exception),
"CredlyOrganization with the uuid nonexistent_organization_id does not exist!",
)
def test_perform_request(self):
- with mock.patch(
- "credentials.apps.badges.credly.api_client.requests.request"
- ) as mock_request:
+ with mock.patch("credentials.apps.badges.credly.api_client.requests.request") as mock_request:
mock_response = mock.Mock()
mock_response.json.return_value = {"key": "value"}
mock_request.return_value = mock_response
@@ -56,55 +49,33 @@ def test_perform_request(self):
mock_request.assert_called_once_with(
"GET",
"https://sandbox-api.credly.com/api/endpoint",
- headers=self.api_client._get_headers(),
+ headers={
+ "Accept": "application/json",
+ "Content-Type": "application/json",
+ "Authorization": "Basic dGVzdF9hcGlfa2V5",
+ },
json=None,
+ timeout=10,
)
self.assertEqual(result, {"key": "value"})
- def test_raise_for_error_success(self):
- response = mock.Mock(spec=Response)
- response.status_code = 200
- self.api_client._raise_for_error(response)
-
- def test_raise_for_error_error(self):
- response = mock.Mock(spec=Response)
- response.status_code = 404
- response.text = "Not Found"
- response.raise_for_status.side_effect = CredlyAPIError(
- f"Credly API: {response.text} ({response.status_code})"
- )
-
- with self.assertRaises(CredlyAPIError) as cm:
- self.api_client._raise_for_error(response)
- self.assertEqual(str(cm.exception), "Credly API: Not Found (404)")
-
def test_fetch_organization(self):
- with mock.patch.object(
- CredlyAPIClient, "perform_request"
- ) as mock_perform_request:
+ with mock.patch.object(CredlyAPIClient, "perform_request") as mock_perform_request:
mock_perform_request.return_value = {"organization": "data"}
result = self.api_client.fetch_organization()
mock_perform_request.assert_called_once_with("get", "")
self.assertEqual(result, {"organization": "data"})
def test_fetch_badge_templates(self):
- with mock.patch.object(
- CredlyAPIClient, "perform_request"
- ) as mock_perform_request:
- mock_perform_request.return_value = {
- "badge_templates": ["template1", "template2"]
- }
+ with mock.patch.object(CredlyAPIClient, "perform_request") as mock_perform_request:
+ mock_perform_request.return_value = {"badge_templates": ["template1", "template2"]}
result = self.api_client.fetch_badge_templates()
- mock_perform_request.assert_called_once_with(
- "get", "badge_templates/?filter=state::active"
- )
+ mock_perform_request.assert_called_once_with("get", "badge_templates/?filter=state::active")
self.assertEqual(result, {"badge_templates": ["template1", "template2"]})
def test_fetch_event_information(self):
event_id = "event123"
- with mock.patch.object(
- CredlyAPIClient, "perform_request"
- ) as mock_perform_request:
+ with mock.patch.object(CredlyAPIClient, "perform_request") as mock_perform_request:
mock_perform_request.return_value = {"event": "data"}
result = self.api_client.fetch_event_information(event_id)
mock_perform_request.assert_called_once_with("get", f"events/{event_id}/")
@@ -112,25 +83,17 @@ def test_fetch_event_information(self):
def test_issue_badge(self):
issue_badge_data = self.badge_data
- with mock.patch.object(
- CredlyAPIClient, "perform_request"
- ) as mock_perform_request:
+ with mock.patch.object(CredlyAPIClient, "perform_request") as mock_perform_request:
mock_perform_request.return_value = {"badge": "issued"}
result = self.api_client.issue_badge(issue_badge_data)
- mock_perform_request.assert_called_once_with(
- "post", "badges/", asdict(issue_badge_data)
- )
+ mock_perform_request.assert_called_once_with("post", "badges/", asdict(issue_badge_data))
self.assertEqual(result, {"badge": "issued"})
def test_revoke_badge(self):
badge_id = "badge123"
data = {"data": "value"}
- with mock.patch.object(
- CredlyAPIClient, "perform_request"
- ) as mock_perform_request:
+ with mock.patch.object(CredlyAPIClient, "perform_request") as mock_perform_request:
mock_perform_request.return_value = {"badge": "revoked"}
result = self.api_client.revoke_badge(badge_id, data)
- mock_perform_request.assert_called_once_with(
- "put", f"badges/{badge_id}/revoke/", data=data
- )
+ mock_perform_request.assert_called_once_with("put", f"badges/{badge_id}/revoke/", data=data)
self.assertEqual(result, {"badge": "revoked"})
diff --git a/credentials/apps/badges/tests/test_issuers.py b/credentials/apps/badges/tests/test_issuers.py
index 77c583869e..45cc07fea4 100644
--- a/credentials/apps/badges/tests/test_issuers.py
+++ b/credentials/apps/badges/tests/test_issuers.py
@@ -16,7 +16,7 @@
User = get_user_model()
-class CredlyBadgeTemplateIssuer(TestCase):
+class CredlyBadgeTemplateIssuerTestCase(TestCase):
issued_credential_type = CredlyBadgeTemplate
issued_user_credential_type = CredlyBadge
issuer = CredlyBadgeTemplateIssuer
@@ -37,10 +37,10 @@ def setUp(self):
)
User.objects.create_user(username="test_user", email="test_email@fff.com", password="test_password")
- def _perform_request(self, method, endpoint, data=None):
+ def _perform_request(self, method, endpoint, data=None): # pylint: disable=unused-argument
fake = faker.Faker()
return {"data": {"id": fake.uuid4(), "state": "issued"}}
-
+
def test_create_user_credential_with_status_awared(self):
# Call create_user_credential with valid arguments
with mock.patch("credentials.apps.badges.issuers.notify_badge_awarded") as mock_notify_badge_awarded:
@@ -88,7 +88,7 @@ def test_create_user_credential_with_status_revoked(self):
).exists()
)
- @patch.object(CredlyAPIClient, 'perform_request', _perform_request)
+ @patch.object(CredlyAPIClient, "perform_request", _perform_request)
def test_issue_credly_badge(self):
# Create a test user credential
user_credential = self.issued_user_credential_type.objects.create(
@@ -134,4 +134,4 @@ def test_issue_credly_badge_with_error(self):
# Check if the user credential state is updated to "error"
user_credential.refresh_from_db()
- self.assertEqual(user_credential.state, "error")
\ No newline at end of file
+ self.assertEqual(user_credential.state, "error")
diff --git a/credentials/apps/badges/tests/test_models.py b/credentials/apps/badges/tests/test_models.py
index 3be5212c5e..cf1f4a425b 100644
--- a/credentials/apps/badges/tests/test_models.py
+++ b/credentials/apps/badges/tests/test_models.py
@@ -102,7 +102,6 @@ def setUp(self):
organization=self.organization, uuid=uuid.uuid4(), name="test_template", state="draft", site=self.site
)
- def test_multiple_requirements_for_badgetemplate(self):
self.requirement1 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
@@ -114,41 +113,29 @@ def test_multiple_requirements_for_badgetemplate(self):
description="Test description",
)
self.requirement3 = BadgeRequirement.objects.create(
- template=self.badge_template,
- event_type="org.openedx.learning.ccx.course.passing.status.updated.v1",
- description="Test description",
- )
-
- requirements = BadgeRequirement.objects.filter(template=self.badge_template)
-
- self.assertEqual(requirements.count(), 3)
- self.assertIn(self.requirement1, requirements)
- self.assertIn(self.requirement2, requirements)
- self.assertIn(self.requirement3, requirements)
-
- def test_multiple_requirements_for_credlybadgetemplate(self):
- self.requirement1 = BadgeRequirement.objects.create(
template=self.credlybadge_template,
event_type="org.openedx.learning.ccx.course.passing.status.updated.v1",
description="Test description",
)
- self.requirement2 = BadgeRequirement.objects.create(
+ self.requirement4 = BadgeRequirement.objects.create(
template=self.credlybadge_template,
event_type="org.openedx.learning.ccx.course.passing.status.updated.v1",
description="Test description",
)
- self.requirement3 = BadgeRequirement.objects.create(
- template=self.credlybadge_template,
- event_type="org.openedx.learning.course.passing.status.updated.v1",
- description="Test description",
- )
- requirements = BadgeRequirement.objects.filter(template=self.credlybadge_template)
+ def test_multiple_requirements_for_badgetemplate(self):
+ requirements = BadgeRequirement.objects.filter(template=self.badge_template)
- self.assertEqual(requirements.count(), 3)
+ self.assertEqual(requirements.count(), 2)
self.assertIn(self.requirement1, requirements)
self.assertIn(self.requirement2, requirements)
+
+ def test_multiple_requirements_for_credlybadgetemplate(self):
+ requirements = BadgeRequirement.objects.filter(template=self.credlybadge_template)
+
+ self.assertEqual(requirements.count(), 2)
self.assertIn(self.requirement3, requirements)
+ self.assertIn(self.requirement4, requirements)
class RequirementFulfillmentCheckTestCase(TestCase):
@@ -184,21 +171,21 @@ def setUp(self):
self.badge_requirement1 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
- group="group1",
+ blend="group1",
)
self.badge_requirement2 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.ccx.course.passing.status.updated.v1",
- group="group1",
+ blend="group1",
)
self.badge_requirement3 = BadgeRequirement.objects.create(
template=self.badge_template, event_type="org.openedx.learning.course.passing.status.updated.v1"
)
def test_requirement_group(self):
- group = self.badge_template.requirements.filter(group="group1")
- self.assertEqual(group.count(), 2)
- self.assertIsNone(self.badge_requirement3.group)
+ groups = self.badge_template.requirements.filter(blend="group1")
+ self.assertEqual(groups.count(), 2)
+ self.assertIsNone(self.badge_requirement3.blend)
class BadgeTemplateUserProgressTestCase(TestCase):
@@ -217,19 +204,19 @@ def setUp(self):
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="A",
+ blend="A",
)
self.requirement2 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="B",
+ blend="B",
)
self.requirement3 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.ccx.course.passing.status.updated.v1",
description="Test description",
- group="C",
+ blend="C",
)
def test_user_progress_success(self):
@@ -297,39 +284,39 @@ def setUp(self):
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="A",
+ blend="A",
)
self.requirement2 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="B",
+ blend="B",
)
self.group_requirement1 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="test-group1",
+ blend="test-group1",
)
self.group_requirement2 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="test-group1",
+ blend="test-group1",
)
self.group_requirement3 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="test-group2",
+ blend="test-group2",
)
self.group_requirement4 = BadgeRequirement.objects.create(
template=self.badge_template,
event_type="org.openedx.learning.course.passing.status.updated.v1",
description="Test description",
- group="test-group2",
+ blend="test-group2",
)
self.progress = BadgeProgress.objects.create(username="test_user", template=self.badge_template)
diff --git a/credentials/apps/badges/tests/test_services.py b/credentials/apps/badges/tests/test_services.py
index 2c3271e9b1..e23af3b8d5 100644
--- a/credentials/apps/badges/tests/test_services.py
+++ b/credentials/apps/badges/tests/test_services.py
@@ -281,13 +281,13 @@ def test_process_one_of_grouped_requirements_penalty(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="Test course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_b = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="Test course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
DataRule.objects.create(
requirement=requirement_a,
@@ -322,13 +322,13 @@ def test_process_mixed_penalty(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="Test course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_b = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="Test course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_c = BadgeRequirement.objects.create(
template=self.badge_template,
@@ -420,13 +420,13 @@ def test_course_a_or_b_completion(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_b = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
DataRule.objects.create(
requirement=requirement_a,
@@ -450,19 +450,19 @@ def test_course_a_or_b_or_c_completion(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B or C course passing award description",
- group="a_or_b_or_c",
+ blend="a_or_b_or_c",
)
requirement_b = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B or C course passing award description",
- group="a_or_b_or_c",
+ blend="a_or_b_or_c",
)
requirement_c = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B or C course passing award description",
- group="a_or_b_or_c",
+ blend="a_or_b_or_c",
)
DataRule.objects.create(
requirement=requirement_a,
@@ -493,7 +493,7 @@ def test_course_a_or_completion(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or course passing award description",
- group="a_or",
+ blend="a_or",
)
DataRule.objects.create(
requirement=requirement,
@@ -510,13 +510,13 @@ def test_course_a_or_b_and_c_completion(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_b = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_c = BadgeRequirement.objects.create(
template=self.badge_template,
@@ -562,25 +562,25 @@ def test_course_a_or_b_and_c_or_d_completion(self):
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_b = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="A or B course passing award description",
- group="a_or_b",
+ blend="a_or_b",
)
requirement_c = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="C or D course passing award description",
- group="c_or_d",
+ blend="c_or_d",
)
requirement_d = BadgeRequirement.objects.create(
template=self.badge_template,
event_type=COURSE_PASSING_EVENT,
description="C or D course passing award description",
- group="c_or_d",
+ blend="c_or_d",
)
DataRule.objects.create(
requirement=requirement_a,
@@ -633,17 +633,18 @@ class TestIdentifyUser(TestCase):
def test_identify_user(self):
username = identify_user(event_type=COURSE_PASSING_EVENT, event_payload=COURSE_PASSING_DATA)
self.assertEqual(username, "test_username")
-
+
def test_identify_user_not_found(self):
event_type = "unknown_event_type"
event_payload = None
with self.assertRaises(BadgesProcessingError) as cm:
- identify_user(event_type="unknown_event_type", event_payload=event_payload)
+ identify_user(event_type="unknown_event_type", event_payload=event_payload)
self.assertEqual(
str(cm.exception),
- f"User data cannot be found (got: None): {event_payload}. Does event {event_type} include user data at all?"
+ f"User data cannot be found (got: None): {event_payload}. "
+ f"Does event {event_type} include user data at all?",
)
@@ -666,18 +667,16 @@ def setUp(self):
is_active=True,
)
DataRule.objects.create(
- requirement=BadgeRequirement.objects.create(
- template=self.badge_template, event_type=COURSE_PASSING_EVENT
- ),
+ requirement=BadgeRequirement.objects.create(template=self.badge_template, event_type=COURSE_PASSING_EVENT),
data_path="is_passing",
operator="eq",
- value="True"
+ value="True",
)
PenaltyDataRule.objects.create(
penalty=BadgePenalty.objects.create(template=self.badge_template, event_type=COURSE_PASSING_EVENT),
data_path="is_passing",
operator="eq",
- value="False"
+ value="False",
)
self.sender = MagicMock()
self.sender.event_type = COURSE_PASSING_EVENT
@@ -711,7 +710,6 @@ def test_process_event_not_found(self):
process_event(sender=sender, kwargs=event_payload)
mock_event_not_found.assert_called_once()
-
def test_process_event_no_user_data(self):
event_payload = CoursePassingStatusData(
is_passing=True,
@@ -722,4 +720,3 @@ def test_process_event_no_user_data(self):
with patch("credentials.apps.badges.processing.generic.logger.error") as mock_no_user_data:
process_event(sender=self.sender, kwargs=event_payload)
mock_no_user_data.assert_called_once()
-
diff --git a/credentials/apps/badges/tests/test_signals.py b/credentials/apps/badges/tests/test_signals.py
index 8971563f7c..0a79663b43 100644
--- a/credentials/apps/badges/tests/test_signals.py
+++ b/credentials/apps/badges/tests/test_signals.py
@@ -41,7 +41,7 @@ def test_progression_signal_emission_and_receiver_execution(self):
self.assertTrue(user_credential.exists())
# Check if user credential status is 'awarded'
- self.assertTrue(user_credential[0].status == "awarded")
+ self.assertEqual(user_credential[0].status, "awarded")
def test_regression_signal_emission_and_receiver_execution(self):
# Emit the signal
@@ -64,4 +64,4 @@ def test_regression_signal_emission_and_receiver_execution(self):
self.assertTrue(user_credential.exists())
# Check if user credential status is 'revoked'
- self.assertTrue(user_credential[0].status == "revoked")
+ self.assertEqual(user_credential[0].status, "revoked")
diff --git a/credentials/apps/badges/tests/test_utils.py b/credentials/apps/badges/tests/test_utils.py
index 658a06d5f5..2d79f873c9 100644
--- a/credentials/apps/badges/tests/test_utils.py
+++ b/credentials/apps/badges/tests/test_utils.py
@@ -134,7 +134,7 @@ def test_badges_checks_non_empty_events(self, mock_get_badging_event_types):
mock_get_badging_event_types.return_value = ["event1", "event2"]
errors = badges_checks()
self.assertEqual(len(errors), 0)
-
+
@patch("credentials.apps.badges.checks.credly_check")
def test_badges_checks_credly_not_configured(self, mock_credly_check):
mock_credly_check.return_value = False
@@ -227,16 +227,16 @@ def test_get_credly_api_base_url_production(self):
class TestGetEventTypeAttrTypeByKeypath(unittest.TestCase):
def test_get_event_type_attr_type_by_keypath(self):
- keypath = "course.course_key"
- result = get_event_type_attr_type_by_keypath(COURSE_PASSING_EVENT, keypath)
+ key_path = "course.course_key"
+ result = get_event_type_attr_type_by_keypath(COURSE_PASSING_EVENT, key_path)
self.assertEqual(result, CourseKey)
def test_get_event_type_attr_type_by_keypath_bool(self):
- keypath = "is_passing"
- result = get_event_type_attr_type_by_keypath(COURSE_PASSING_EVENT, keypath)
+ key_path = "is_passing"
+ result = get_event_type_attr_type_by_keypath(COURSE_PASSING_EVENT, key_path)
self.assertEqual(result, bool)
def test_get_event_type_attr_type_by_keypath_not_found(self):
- keypath = "course.id"
- result = get_event_type_attr_type_by_keypath(COURSE_PASSING_EVENT, keypath)
+ key_path = "course.id"
+ result = get_event_type_attr_type_by_keypath(COURSE_PASSING_EVENT, key_path)
self.assertIsNone(result)
diff --git a/credentials/apps/badges/tests/test_webhooks.py b/credentials/apps/badges/tests/test_webhooks.py
index 51f6e84cb2..db95b8d740 100644
--- a/credentials/apps/badges/tests/test_webhooks.py
+++ b/credentials/apps/badges/tests/test_webhooks.py
@@ -13,14 +13,14 @@ def mocked_handle_event(**kwargs):
return "test"
-def get_organization(self, organization_id):
- organization = MagicMock(spec=CredlyOrganization) # Create a mocked instance of CredlyOrganization
+def get_organization(self, organization_id): # pylint: disable=unused-argument
+ organization = MagicMock(spec=CredlyOrganization)
organization.uuid = organization_id
organization.api_key = "test_api_key"
return organization
-def perform_request(self, method, endpoint, data=None):
+def perform_request(self, method, endpoint, data=None): # pylint: disable=unused-argument
return {"key": "value"}
@@ -90,9 +90,7 @@ def test_webhook_deleted_event(self):
@patch.object(CredlyAPIClient, "_get_organization", get_organization)
@patch.object(CredlyAPIClient, "perform_request", perform_request)
def test_webhook_nonexistent_event(self):
- with patch(
- "credentials.apps.badges.credly.webhooks.logger.error"
- ) as mock_handle:
+ with patch("credentials.apps.badges.credly.webhooks.logger.error") as mock_handle:
req = self.rf.post(
"/credly/webhookd/",
data={
diff --git a/credentials/apps/badges/toggles.py b/credentials/apps/badges/toggles.py
index bd54217ded..b82d510d5f 100644
--- a/credentials/apps/badges/toggles.py
+++ b/credentials/apps/badges/toggles.py
@@ -32,5 +32,6 @@ def check_badges_enabled(func):
def wrapper(*args, **kwargs):
if is_badges_enabled():
return func(*args, **kwargs)
+ return None
return wrapper
diff --git a/credentials/apps/badges/utils.py b/credentials/apps/badges/utils.py
index fc1ad8f6d2..719ae66ea5 100644
--- a/credentials/apps/badges/utils.py
+++ b/credentials/apps/badges/utils.py
@@ -1,4 +1,5 @@
import inspect
+from typing import Union
import attr
from attrs import asdict
@@ -29,7 +30,7 @@ def credly_check():
"CREDLY_SANDBOX_API_BASE_URL",
"USE_SANDBOX",
)
- return all([key in credly_settings.keys() for key in keys])
+ return all(key in credly_settings.keys() for key in keys)
def keypath(payload, keys_path):
@@ -100,7 +101,7 @@ def get_user_data(data: attr.s) -> UserData:
return None
-def extract_payload(public_signal_kwargs: dict) -> attr.s:
+def extract_payload(public_signal_kwargs: dict) -> Union[None, attr.s]:
"""
Extracts the event payload from the event data.
@@ -113,6 +114,7 @@ def extract_payload(public_signal_kwargs: dict) -> attr.s:
for value in public_signal_kwargs.values():
if attr.has(value):
return value
+ return None
def get_event_type_data(event_type: str) -> attr.s:
@@ -169,13 +171,13 @@ def get_data_keypaths(data):
return keypaths
-def get_event_type_attr_type_by_keypath(event_type: str, keypath: str):
+def get_event_type_attr_type_by_keypath(event_type: str, key_path: str):
"""
Extracts the attribute type for a given keypath in the event type.
Parameters:
- event_type: The event type to extract dataclass for.
- - keypath: The keypath to extract attribute type for.
+ - key_path: The keypath to extract attribute type for.
Returns:
type: The attribute type for the given keypath in the event data.
@@ -184,12 +186,12 @@ def get_event_type_attr_type_by_keypath(event_type: str, keypath: str):
data = get_event_type_data(event_type)
data_attrs = attr.fields(data)
- def get_attr_type_by_keypath(data_attrs, keypath):
+ def get_attr_type_by_keypath(data_attrs, key_path):
"""
Extracts the attribute type for a given keypath in the dataclass.
"""
- keypath_parts = keypath.split(".")
+ keypath_parts = key_path.split(".")
for attr_ in data_attrs:
if attr_.name == keypath_parts[0]:
if len(keypath_parts) == 1:
@@ -198,4 +200,4 @@ def get_attr_type_by_keypath(data_attrs, keypath):
return get_attr_type_by_keypath(attr.fields(attr_.type), ".".join(keypath_parts[1:]))
return None
- return get_attr_type_by_keypath(data_attrs, keypath)
+ return get_attr_type_by_keypath(data_attrs, key_path)
diff --git a/credentials/conf/locale/eo/LC_MESSAGES/django.mo b/credentials/conf/locale/eo/LC_MESSAGES/django.mo
index c1f43af035..b3f90d165d 100644
Binary files a/credentials/conf/locale/eo/LC_MESSAGES/django.mo and b/credentials/conf/locale/eo/LC_MESSAGES/django.mo differ
diff --git a/credentials/conf/locale/eo/LC_MESSAGES/django.po b/credentials/conf/locale/eo/LC_MESSAGES/django.po
index cec0f618d8..1bd112473b 100644
--- a/credentials/conf/locale/eo/LC_MESSAGES/django.po
+++ b/credentials/conf/locale/eo/LC_MESSAGES/django.po
@@ -6,8 +6,8 @@
msgid ""
msgstr ""
"Project-Id-Version: 0.1a\n"
-"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
-"POT-Creation-Date: 2024-05-27 10:13+0000\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-05-31 13:57+0000\n"
"PO-Revision-Date: 2024-05-27 10:13:41.472759\n"
"Last-Translator: \n"
"Language-Team: openedx-translation \n"
@@ -17,141 +17,157 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:72 credentials/apps/badges/admin.py:117
msgid "No rules specified."
msgstr "Nö rülés spéçïfïéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:178
msgid "Badge templates were successfully updated."
msgstr ""
-"Bädgé témplätés wéré süççéssfüllý üpdätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя #"
+"Bädgé témplätés wéré süççéssfüllý üpdätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя #"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:180
msgid "API key"
msgstr "ÀPÌ kéý Ⱡ'σяєм ιρѕυм #"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:186
msgid "Pre-configured from the environment."
msgstr ""
-"Pré-çönfïgüréd fröm thé énvïrönmént. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυ#"
-
-#: apps/badges/admin.py
+"Pré-çönfïgüréd fröm thé énvïrönmént. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
+
+#: credentials/apps/badges/admin.py:248
+#, fuzzy
+#| msgid ""
+#| "\n"
+#| " WARNING: avoid configuration updates on activated "
+#| "badges.\n"
+#| " Active badge templates are continuously processed and "
+#| "learners may already have partial progress on them.\n"
+#| " Any changes in badge template requirements (including "
+#| "data rules) will affect learners' experience!\n"
+#| " "
msgid ""
"\n"
-" WARNING: avoid configuration updates on activated badges.\n"
-" Active badge templates are continuously processed and learners may already have partial progress on them.\n"
-" Any changes in badge template requirements (including data rules) will affect learners' experience!\n"
+" WARNING: avoid configuration updates on activated "
+"badges.\n"
+" Active badge templates are continuously processed and "
+"learners may already have progress on them.\n"
+" Any changes in badge template requirements (including "
+"data rules) will affect learners' experience!\n"
" "
msgstr ""
"\n"
-" WÀRNÌNG: ävöïd çönfïgürätïön üpdätés ön äçtïvätéd ßädgés.\n"
-" Àçtïvé ßädgé témplätés äré çöntïnüöüslý pröçésséd änd léärnérs mäý älréädý hävé pärtïäl prögréss ön thém.\n"
-" Àný çhängés ïn ßädgé témpläté réqüïréménts (ïnçlüdïng dätä rülés) wïll äfféçt léärnérs' éxpérïénçé!\n"
-" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕ#"
-
-#: apps/badges/admin.py
+" WÀRNÌNG: ävöïd çönfïgürätïön üpdätés ön äçtïvätéd "
+"ßädgés.\n"
+" Àçtïvé ßädgé témplätés äré çöntïnüöüslý pröçésséd änd "
+"léärnérs mäý älréädý hävé pärtïäl prögréss ön thém.\n"
+" Àný çhängés ïn ßädgé témpläté réqüïréménts (ïnçlüdïng "
+"dätä rülés) wïll äfféçt léärnérs' éxpérïénçé!\n"
+" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg "
+"єłιт, ѕє∂ ∂σ єιυѕ#"
+
+#: credentials/apps/badges/admin.py:297
msgid "Active badge template cannot be deleted."
msgstr ""
-"Àçtïvé ßädgé témpläté çännöt ßé délétéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя#"
+"Àçtïvé ßädgé témpläté çännöt ßé délétéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя#"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:307
msgid "Active badge templates cannot be deleted."
msgstr ""
-"Àçtïvé ßädgé témplätés çännöt ßé délétéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя #"
+"Àçtïvé ßädgé témplätés çännöt ßé délétéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя #"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:319
msgid "icon"
msgstr "ïçön Ⱡ'σяєм ι#"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:332
msgid "Active badge template must have at least one requirement."
msgstr ""
-"Àçtïvé ßädgé témpläté müst hävé ät léäst öné réqüïrémént. Ⱡ'σяєм ιρѕυм ∂σłσя"
-" ѕιт αмєт, ¢σηѕє¢тєтυя α#"
+"Àçtïvé ßädgé témpläté müst hävé ät léäst öné réqüïrémént. Ⱡ'σяєм ιρѕυм ∂σłσя "
+"ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:391 credentials/apps/badges/admin.py:448
msgid "badge template"
msgstr "ßädgé témpläté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: apps/badges/admin_forms.py
+#: credentials/apps/badges/admin_forms.py:48
msgid "You can't provide an API key for a configured organization."
msgstr ""
"Ýöü çän't prövïdé än ÀPÌ kéý för ä çönfïgüréd örgänïzätïön. Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/badges/admin_forms.py
+#: credentials/apps/badges/admin_forms.py:98
msgid "All requirements must belong to the same template."
msgstr ""
"Àll réqüïréménts müst ßélöng tö thé sämé témpläté. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/badges/admin_forms.py
+#: credentials/apps/badges/admin_forms.py:141
msgid "Value must be a boolean."
msgstr "Välüé müst ßé ä ßööléän. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢ση#"
-#: apps/badges/issuers.py
+#: credentials/apps/badges/issuers.py:136
msgid "Open edX internal user credential was revoked"
msgstr ""
"Öpén édX ïntérnäl üsér çrédéntïäl wäs révökéd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:37
msgid "Put your Credly Organization ID here."
msgstr ""
-"Püt ýöür Çrédlý Örgänïzätïön ÌD héré. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυ#"
+"Püt ýöür Çrédlý Örgänïzätïön ÌD héré. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυ#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:40
msgid "Credly API shared secret for Credly Organization."
msgstr ""
"Çrédlý ÀPÌ shäréd séçrét för Çrédlý Örgänïzätïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:47
msgid "Verbose name for Credly Organization."
msgstr ""
-"Vérßösé nämé för Çrédlý Örgänïzätïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυ#"
+"Vérßösé nämé för Çrédlý Örgänïzätïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυ#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:87
msgid "Unique badge template ID."
msgstr "Ûnïqüé ßädgé témpläté ÌD. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:88
msgid "Badge template name."
msgstr "Bädgé témpläté nämé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:89
msgid "Badge template description."
msgstr "Bädgé témpläté désçrïptïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:91
msgid "Badge template type."
msgstr "Bädgé témpläté týpé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:94
msgid "Credly badge template state (auto-managed)."
msgstr ""
"Çrédlý ßädgé témpläté stäté (äütö-mänägéd). Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:143
msgid "Credly Organization - template owner."
msgstr ""
-"Çrédlý Örgänïzätïön - témpläté öwnér. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυ#"
+"Çrédlý Örgänïzätïön - témpläté öwnér. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυ#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:172
msgid "Badge template this requirement serves for."
msgstr ""
"Bädgé témpläté thïs réqüïrémént sérvés för. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:178
msgid ""
"Public signal type. Available events are configured in \"BADGES_CONFIG\" "
"setting. The crucial aspect for event to carry UserData in its payload."
@@ -159,351 +175,358 @@ msgstr ""
"Püßlïç sïgnäl týpé. Àväïläßlé événts äré çönfïgüréd ïn \"BÀDGÉS_ÇÖNFÌG\" "
"séttïng. Thé çrüçïäl äspéçt för évént tö çärrý ÛsérDätä ïn ïts päýlöäd. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ "
-"тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм,"
-" qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
+"тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, "
+"qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ єѕт#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:182
msgid "Provide more details if needed."
msgstr "Prövïdé möré détäïls ïf néédéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:188
+#, fuzzy
+#| msgid ""
+#| "Optional. Put requirements into the same arbitrary Group ID to make them "
+#| "interchangeable (OR processing logic applies)."
msgid ""
-"Optional. Put requirements into the same arbitrary Group ID to make them "
-"interchangeable (OR processing logic applies)."
+"Optional. Group requirements together using the same Group ID for "
+"interchangeable (OR processing logic)."
msgstr ""
"Öptïönäl. Püt réqüïréménts ïntö thé sämé ärßïträrý Gröüp ÌD tö mäké thém "
"ïntérçhängéäßlé (ÖR pröçéssïng lögïç äpplïés). Ⱡ'σяєм ιρѕυм#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:190 credentials/apps/badges/models.py:544
+msgid "group"
+msgstr "gröüp"
+
+#: credentials/apps/badges/models.py:292
msgid ""
-"Public signal's data payload nested property path, e.g: "
-"\"user.pii.username\"."
+"Public signal's data payload nested property path, e.g: \"user.pii.username"
+"\"."
msgstr ""
-"Püßlïç sïgnäl's dätä päýlöäd néstéd pröpértý päth, é.g: "
-"\"üsér.pïï.üsérnämé\". Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
+"Püßlïç sïgnäl's dätä päýlöäd néstéd pröpértý päth, é.g: \"üsér.pïï.üsérnämé"
+"\". Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:293
msgid "key path"
msgstr "kéý päth Ⱡ'σяєм ιρѕυм ∂#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:299
msgid ""
-"Expected value comparison operator. "
-"https://docs.python.org/3/library/operator.html"
+"Expected value comparison operator. https://docs.python.org/3/library/"
+"operator.html"
msgstr ""
-"Éxpéçtéd välüé çömpärïsön öpérätör. "
-"https://döçs.pýthön.örg/3/lïßrärý/öpérätör.html Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,"
-" ¢σηѕє¢т#"
+"Éxpéçtéd välüé çömpärïsön öpérätör. https://döçs.pýthön.örg/3/lïßrärý/"
+"öpérätör.html Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:303
msgid "Expected value for the nested property, e.g: \"cucumber1997\"."
msgstr ""
"Éxpéçtéd välüé för thé néstéd pröpértý, é.g: \"çüçümßér1997\". Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:304
msgid "expected value"
msgstr "éxpéçtéd välüé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:363
msgid "Parent requirement for this data rule."
msgstr ""
-"Pärént réqüïrémént för thïs dätä rülé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя#"
+"Pärént réqüïrémént för thïs dätä rülé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:388
msgid "Badge template this penalty serves for."
msgstr ""
-"Bädgé témpläté thïs pénältý sérvés för. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя#"
+"Bädgé témpläté thïs pénältý sérvés för. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:394
msgid ""
-"Public signal type. Use namespaced types, e.g: "
-"\"org.openedx.learning.student.registration.completed.v1\""
+"Public signal type. Use namespaced types, e.g: \"org.openedx.learning."
+"student.registration.completed.v1\""
msgstr ""
-"Püßlïç sïgnäl týpé. Ûsé näméspäçéd týpés, é.g: "
-"\"örg.öpénédx.léärnïng.stüdént.régïsträtïön.çömplétéd.v1\" Ⱡ'σяєм ιρѕυм "
-"∂σłσя ѕιт αм#"
+"Püßlïç sïgnäl týpé. Ûsé näméspäçéd týpés, é.g: \"örg.öpénédx.léärnïng."
+"stüdént.régïsträtïön.çömplétéd.v1\" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:399
msgid "Badge requirements for which this penalty is defined."
msgstr ""
-"Bädgé réqüïréménts för whïçh thïs pénältý ïs défïnéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт"
-" αмєт, ¢σηѕє¢тєтυя α#"
+"Bädgé réqüïréménts för whïçh thïs pénältý ïs défïnéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
+"αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:403
msgid "Badge penalties"
msgstr "Bädgé pénältïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:437
msgid "Parent penalty for this data rule."
msgstr ""
"Pärént pénältý för thïs dätä rülé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:469
msgid "badge progress records"
msgstr "ßädgé prögréss réçörds Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:543
msgid "Group ID for the requirement."
msgstr "Gröüp ÌD för thé réqüïrémént. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:573
msgid "Credly badge issuing state"
msgstr "Çrédlý ßädgé ïssüïng stäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:581
msgid "Credly service badge identifier"
msgstr "Çrédlý sérvïçé ßädgé ïdéntïfïér Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:20
msgid "Activate selected entries"
msgstr "Àçtïväté séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:28
#, python-brace-format
msgid "1 {model_name} entry was successfully activated."
msgstr ""
"1 {model_name} éntrý wäs süççéssfüllý äçtïvätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:30
#, python-brace-format
msgid "{count} {model_name} entries were successfully activated."
msgstr ""
-"{count} {model_name} éntrïés wéré süççéssfüllý äçtïvätéd. Ⱡ'σяєм ιρѕυм ∂σłσя"
-" ѕιт αмєт, ¢σηѕє¢тєтυя #"
+"{count} {model_name} éntrïés wéré süççéssfüllý äçtïvätéd. Ⱡ'σяєм ιρѕυм ∂σłσя "
+"ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:34
msgid "Deactivate selected entries"
msgstr "Déäçtïväté séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:42
#, python-brace-format
msgid "1 {model_name} entry was successfully deactivated."
msgstr ""
"1 {model_name} éntrý wäs süççéssfüllý déäçtïvätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя #"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:44
#, python-brace-format
msgid "{count} {model_name} entries were successfully deactivated."
msgstr ""
"{count} {model_name} éntrïés wéré süççéssfüllý déäçtïvätéd. Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:48
msgid "Add is_staff to selected entries"
msgstr ""
"Àdd ïs_stäff tö séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:56 credentials/apps/core/admin.py:70
+#: credentials/apps/core/admin.py:84 credentials/apps/core/admin.py:103
#, python-brace-format
msgid "1 {model_name} entry was successfully changed."
msgstr ""
"1 {model_name} éntrý wäs süççéssfüllý çhängéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυ#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:58 credentials/apps/core/admin.py:72
+#: credentials/apps/core/admin.py:86 credentials/apps/core/admin.py:105
#, python-brace-format
msgid "{count} {model_name} entries were successfully changed."
msgstr ""
"{count} {model_name} éntrïés wéré süççéssfüllý çhängéd. Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:62
msgid "Remove is_staff from selected entries"
msgstr ""
-"Rémövé ïs_stäff fröm séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυ#"
+"Rémövé ïs_stäff fröm séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυ#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:76
msgid "Add is_superuser to selected entries"
msgstr ""
-"Àdd ïs_süpérüsér tö séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυ#"
+"Àdd ïs_süpérüsér tö séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:90
msgid "Remove is_superuser from selected entries"
msgstr ""
-"Rémövé ïs_süpérüsér fröm séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя #"
+"Rémövé ïs_süpérüsér fröm séléçtéd éntrïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя #"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:126
msgid "Personal info"
msgstr "Pérsönäl ïnfö Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:127
msgid "Permissions"
msgstr "Pérmïssïöns Ⱡ'σяєм ιρѕυм ∂σłσя #"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:128
msgid "Important dates"
msgstr "Ìmpörtänt dätés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:155
msgid "URLs"
msgstr "ÛRLs Ⱡ'σяєм ι#"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:170
msgid "Social Sharing"
msgstr "Söçïäl Shärïng Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: apps/core/forms.py
+#: credentials/apps/core/forms.py:12
msgid "A Facebook app ID is required to enable Facebook sharing."
msgstr ""
-"À Fäçéßöök äpp ÌD ïs réqüïréd tö énäßlé Fäçéßöök shärïng. Ⱡ'σяєм ιρѕυм ∂σłσя"
-" ѕιт αмєт, ¢σηѕє¢тєтυя α#"
+"À Fäçéßöök äpp ÌD ïs réqüïréd tö énäßlé Fäçéßöök shärïng. Ⱡ'σяєм ιρѕυм ∂σłσя "
+"ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:24
msgid "Platform Name"
msgstr "Plätförm Nämé Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:25
msgid "Name of your Open edX platform"
msgstr "Nämé öf ýöür Öpén édX plätförm Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:31
msgid "Segment Key"
msgstr "Ségmént Kéý Ⱡ'σяєм ιρѕυм ∂σłσя #"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:31
msgid "Segment write/API key."
msgstr "Ségmént wrïté/ÀPÌ kéý. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:34
msgid "Theme Name"
msgstr "Thémé Nämé Ⱡ'σяєм ιρѕυм ∂σłσ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:35
msgid ""
"Name of of the theme to use for this site. This value should be lower-cased."
msgstr ""
-"Nämé öf öf thé thémé tö üsé för thïs sïté. Thïs välüé shöüld ßé löwér-çäséd."
-" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
+"Nämé öf öf thé thémé tö üsé för thïs sïté. Thïs välüé shöüld ßé löwér-çäséd. "
+"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:48
msgid "LMS base url for custom site"
msgstr "LMS ßäsé ürl för çüstöm sïté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:49
msgid "Root URL of this site's LMS (e.g. https://courses.stage.edx.org)"
msgstr ""
"Rööt ÛRL öf thïs sïté's LMS (é.g. https://çöürsés.stägé.édx.örg) Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:54
msgid "Catalog API URL"
msgstr "Çätälög ÀPÌ ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:55
msgid "Root URL of the Catalog API (e.g. https://api.edx.org/catalog/v1/)"
msgstr ""
"Rööt ÛRL öf thé Çätälög ÀPÌ (é.g. https://äpï.édx.örg/çätälög/v1/) Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:60
msgid "Terms of Service URL"
msgstr "Térms öf Sérvïçé ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:65
msgid "Privacy Policy URL"
msgstr "Prïväçý Pölïçý ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:70
msgid "Homepage URL"
msgstr "Hömépägé ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:75
msgid "Company Name"
msgstr "Çömpäný Nämé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:81
msgid "Verified Certificate URL"
msgstr "Vérïfïéd Çértïfïçäté ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢ση#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:87
msgid "Certificate Help URL"
msgstr "Çértïfïçäté Hélp ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:88
msgid "URL of page for questions about certificates"
msgstr ""
"ÛRL öf pägé för qüéstïöns äßöüt çértïfïçätés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:93
msgid "Enable Learner Records"
msgstr "Énäßlé Léärnér Réçörds Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:94
msgid "Enable the Records feature. The LMS has a similar setting."
msgstr ""
"Énäßlé thé Réçörds féätüré. Thé LMS häs ä sïmïlär séttïng. Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:98
msgid "Learner Records Help URL"
msgstr "Léärnér Réçörds Hélp ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢ση#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:99
msgid "URL of page for questions about Learner Records"
msgstr ""
-"ÛRL öf pägé för qüéstïöns äßöüt Léärnér Réçörds Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,"
-" ¢σηѕє¢тєтυя α#"
+"ÛRL öf pägé för qüéstïöns äßöüt Léärnér Réçörds Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
+"¢σηѕє¢тєтυя α#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:105
msgid "Facebook App ID"
msgstr "Fäçéßöök Àpp ÌD Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:106
msgid "Facebook app ID used for sharing"
msgstr ""
"Fäçéßöök äpp ÌD üséd för shärïng Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:112
msgid "Twitter Username"
msgstr "Twïttér Ûsérnämé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:113
msgid "Twitter username included in tweeted credentials. Do NOT include @."
msgstr ""
"Twïttér üsérnämé ïnçlüdéd ïn twéétéd çrédéntïäls. Dö NÖT ïnçlüdé @. Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:119
msgid "Enable Facebook sharing"
msgstr "Énäßlé Fäçéßöök shärïng Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:119
msgid "Enable sharing via Facebook"
msgstr "Énäßlé shärïng vïä Fäçéßöök Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:122
msgid "Enable LinkedIn sharing"
msgstr "Énäßlé LïnkédÌn shärïng Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:122
msgid "Enable sharing via LinkedIn"
msgstr "Énäßlé shärïng vïä LïnkédÌn Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:125
msgid "Enable Twitter sharing"
msgstr "Énäßlé Twïttér shärïng Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:125
msgid "Enable sharing via Twitter"
msgstr "Énäßlé shärïng vïä Twïttér Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:202
msgid "Full Name"
msgstr "Füll Nämé Ⱡ'σяєм ιρѕυм ∂σł#"
-#: apps/credentials/forms.py
+#: credentials/apps/credentials/forms.py:48
msgid ""
"All authoring organizations of the program MUST have a certificate image "
"defined!"
@@ -511,44 +534,43 @@ msgstr ""
"Àll äüthörïng örgänïzätïöns öf thé prögräm MÛST hävé ä çértïfïçäté ïmägé "
"défïnéd! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:57
msgid "The image file size must be less than 250KB."
msgstr ""
"Thé ïmägé fïlé sïzé müst ßé léss thän 250KB. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:67
msgid "Invalid course key."
msgstr "Ìnvälïd çöürsé kéý. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
-#: apps/credentials/models.py
-msgid ""
-"Signatory organization name if its different from issuing organization."
+#: credentials/apps/credentials/models.py:98
+msgid "Signatory organization name if its different from issuing organization."
msgstr ""
"Sïgnätörý örgänïzätïön nämé ïf ïts dïfférént fröm ïssüïng örgänïzätïön. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя#"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:101
msgid "Image must be square PNG files. The file size should be under 250KB."
msgstr ""
"Ìmägé müst ßé sqüäré PNG fïlés. Thé fïlé sïzé shöüld ßé ündér 250KB. Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:165
msgid "awarded"
msgstr "äwärdéd Ⱡ'σяєм ιρѕυм #"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:166
msgid "revoked"
msgstr "révökéd Ⱡ'σяєм ιρѕυм #"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:184
msgid "URL at which the credential can be downloaded"
msgstr ""
"ÛRL ät whïçh thé çrédéntïäl çän ßé döwnlöädéd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:216
msgid ""
"The certificate available date and time that is set in Studio and copied to "
"Credentials. This should be edited in Studio."
@@ -556,41 +578,40 @@ msgstr ""
"Thé çértïfïçäté äväïläßlé däté änd tïmé thät ïs sét ïn Stüdïö änd çöpïéd tö "
"Çrédéntïäls. Thïs shöüld ßé édïtéd ïn Stüdïö. Ⱡ'σяєм ιρѕυ#"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:269
msgid "Program UUID"
msgstr "Prögräm ÛÛÌD Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:282
msgid ""
-"Display the associated organization's name (e.g. ACME University) instead of"
-" its short name (e.g. ACMEx)"
+"Display the associated organization's name (e.g. ACME University) instead of "
+"its short name (e.g. ACMEx)"
msgstr ""
-"Dïspläý thé ässöçïätéd örgänïzätïön's nämé (é.g. ÀÇMÉ Ûnïvérsïtý) ïnstéäd öf"
-" ïts shört nämé (é.g. ÀÇMÉx) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
+"Dïspläý thé ässöçïätéd örgänïzätïön's nämé (é.g. ÀÇMÉ Ûnïvérsïtý) ïnstéäd öf "
+"ïts shört nämé (é.g. ÀÇMÉx) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:285
msgid "Use organization name"
msgstr "Ûsé örgänïzätïön nämé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/credentials/views.py
+#: credentials/apps/credentials/views.py:63
#, python-brace-format
msgid "{first_org} and {second_org}"
msgstr "{first_org} änd {second_org} Ⱡ'σяєм ιρѕυм ∂σłσя #"
-#: apps/credentials/views.py
+#: credentials/apps/credentials/views.py:67
#, python-brace-format
msgid "{series_of_orgs}, and {last_org}"
msgstr "{series_of_orgs}, änd {last_org} Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
-#: apps/credentials/views.py
+#: credentials/apps/credentials/views.py:123
#, python-brace-format
-msgid ""
-"I completed a course at {platform_name}. Take a look at my certificate:"
+msgid "I completed a course at {platform_name}. Take a look at my certificate:"
msgstr ""
"Ì çömplétéd ä çöürsé ät {platform_name}. Täké ä löök ät mý çértïfïçäté: "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html
+#: credentials/apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html:7
msgid ""
"successfully completed all courses and received passing grades for a "
"Professional Certificate in"
@@ -598,166 +619,167 @@ msgstr ""
"süççéssfüllý çömplétéd äll çöürsés änd réçéïvéd pässïng grädés för ä "
"Pröféssïönäl Çértïfïçäté ïn Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html
+#: credentials/apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html:11
msgid "Professional Certificate"
msgstr "Pröféssïönäl Çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢ση#"
-#: apps/edx_django_extensions/views.py
+#: credentials/apps/edx_django_extensions/views.py:24
msgid "Cache cleared."
msgstr "Çäçhé çléäréd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: apps/edx_django_extensions/views.py
+#: credentials/apps/edx_django_extensions/views.py:26
#, python-brace-format
msgid "{action} is not a valid action."
msgstr "{action} ïs nöt ä välïd äçtïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/records/api.py
+#: credentials/apps/records/api.py:230
msgid "N/A"
msgstr "N/À Ⱡ'σяєм#"
-#: apps/records/models.py
+#: credentials/apps/records/models.py:76
msgid "sent"
msgstr "sént Ⱡ'σяєм ι#"
-#: apps/records/models.py
+#: credentials/apps/records/models.py:77
msgid "other"
msgstr "öthér Ⱡ'σяєм ιρѕ#"
-#: apps/records/models.py
+#: credentials/apps/records/models.py:94
msgid "User credit pathways can only be connected to credit pathways."
msgstr ""
"Ûsér çrédït päthwäýs çän önlý ßé çönnéçtéd tö çrédït päthwäýs. Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/records/views.py
+#: credentials/apps/records/views.py:119
msgid "Program Listing View"
msgstr "Prögräm Lïstïng Vïéw Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/records/views.py
+#: credentials/apps/records/views.py:121
msgid ""
-"The following is a list of all active programs for which program records are"
-" being generated."
+"The following is a list of all active programs for which program records are "
+"being generated."
msgstr ""
-"Thé föllöwïng ïs ä lïst öf äll äçtïvé prögräms för whïçh prögräm réçörds äré"
-" ßéïng générätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
+"Thé föllöwïng ïs ä lïst öf äll äçtïvé prögräms för whïçh prögräm réçörds äré "
+"ßéïng générätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
-#: apps/verifiable_credentials/admin.py
+#: credentials/apps/verifiable_credentials/admin.py:15
msgid "Issuer ID"
msgstr "Ìssüér ÌD Ⱡ'σяєм ιρѕυм ∂σł#"
-#: apps/verifiable_credentials/admin.py
+#: credentials/apps/verifiable_credentials/admin.py:75
msgid "At least one Issuer must be always enabled!"
msgstr ""
"Àt léäst öné Ìssüér müst ßé älwäýs énäßléd! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: apps/verifiable_credentials/composition/open_badges.py
+#: credentials/apps/verifiable_credentials/composition/open_badges.py:59
msgid "Open Badges Specification v3.0"
msgstr "Öpén Bädgés Spéçïfïçätïön v3.0 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
-#: apps/verifiable_credentials/composition/open_badges.py
+#: credentials/apps/verifiable_credentials/composition/open_badges.py:100
msgid "Open Badges Specification v3.0.1"
msgstr ""
"Öpén Bädgés Spéçïfïçätïön v3.0.1 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
-#: apps/verifiable_credentials/composition/status_list.py
-#: apps/verifiable_credentials/storages/status_list.py
+#: credentials/apps/verifiable_credentials/composition/status_list.py:100
+#: credentials/apps/verifiable_credentials/storages/status_list.py:17
msgid "Status List 2021"
msgstr "Stätüs Lïst 2021 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
-#: apps/verifiable_credentials/composition/verifiable_credentials.py
+#: credentials/apps/verifiable_credentials/composition/verifiable_credentials.py:21
msgid "Verifiable Credentials Data Model v1.1"
msgstr ""
-"Vérïfïäßlé Çrédéntïäls Dätä Mödél v1.1 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя#"
+"Vérïfïäßlé Çrédéntïäls Dätä Mödél v1.1 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя#"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:56
#, python-brace-format
msgid "Couldn't find such issuance line: [{issuance_uuid}]"
msgstr ""
"Çöüldn't fïnd süçh ïssüänçé lïné: [{issuance_uuid}] Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя#"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:62
#, python-brace-format
msgid "Seems credential isn't active anymore: [{credential_id}]"
msgstr ""
"Sééms çrédéntïäl ïsn't äçtïvé änýmöré: [{credential_id}] Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:99
msgid "Provided data didn't validate"
msgstr "Prövïdéd dätä dïdn't välïdäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:125
msgid "Issued verifiable credential can't be verified!"
msgstr ""
-"Ìssüéd vérïfïäßlé çrédéntïäl çän't ßé vérïfïéd! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,"
-" ¢σηѕє¢тєтυя α#"
+"Ìssüéd vérïfïäßlé çrédéntïäl çän't ßé vérïfïéd! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
+"¢σηѕє¢тєтυя α#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:45
msgid "Related Open edX learner credential"
msgstr ""
"Rélätéd Öpén édX léärnér çrédéntïäl Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:47
msgid "Completeness indicator"
msgstr "Çömpléténéss ïndïçätör Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:48
+#: credentials/apps/verifiable_credentials/issuance/models.py:273
msgid "Issuer DID"
msgstr "Ìssüér DÌD Ⱡ'σяєм ιρѕυм ∂σłσ#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:49
msgid "Target storage identifier"
msgstr "Tärgét störägé ïdéntïfïér Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:53
msgid "Verifiable credential subject DID"
msgstr ""
"Vérïfïäßlé çrédéntïäl süßjéçt DÌD Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:59
msgid "Verifiable credential specification to use"
msgstr ""
-"Vérïfïäßlé çrédéntïäl spéçïfïçätïön tö üsé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя #"
+"Vérïfïäßlé çrédéntïäl spéçïfïçätïön tö üsé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя #"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:66
msgid "Defines a position in the Status List sequence"
msgstr ""
"Défïnés ä pösïtïön ïn thé Stätüs Lïst séqüénçé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя α#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:72
msgid "Keeps track on a corresponding user credential's status"
msgstr ""
"Kééps träçk ön ä çörréspöndïng üsér çrédéntïäl's stätüs Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:109
msgid "program certificate"
msgstr "prögräm çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:110
msgid "course certificate"
msgstr "çöürsé çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:123
#, python-brace-format
msgid "program certificate for passing a program {program_title}"
msgstr ""
-"prögräm çértïfïçäté för pässïng ä prögräm {program_title} Ⱡ'σяєм ιρѕυм ∂σłσя"
-" ѕιт αмєт, ¢σηѕє¢тєтυя #"
+"prögräm çértïfïçäté för pässïng ä prögräm {program_title} Ⱡ'σяєм ιρѕυм ∂σłσя "
+"ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:136
#, python-brace-format
msgid ", with total {hours_of_effort} Hours of effort required to complete it"
msgstr ""
", wïth tötäl {hours_of_effort} Höürs öf éffört réqüïréd tö çömplété ït "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:144
#, python-brace-format
msgid ""
"{credential_type} is granted on program {program_title} completion offered "
@@ -769,43 +791,43 @@ msgstr ""
"{program_title} prögräm ïnçlüdés {course_count} çöürsé(s){effort_info}. "
"Ⱡ'σяєм#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:165
#, python-brace-format
msgid ""
-"{recipient_fullname} successfully completed all courses and received passing"
-" grades for a Professional Certificate in {program_title} a program offered "
+"{recipient_fullname} successfully completed all courses and received passing "
+"grades for a Professional Certificate in {program_title} a program offered "
"by {organizations}, in collaboration with {platform_name}."
msgstr ""
-"{recipient_fullname} süççéssfüllý çömplétéd äll çöürsés änd réçéïvéd pässïng"
-" grädés för ä Pröféssïönäl Çértïfïçäté ïn {program_title} ä prögräm öfféréd "
+"{recipient_fullname} süççéssfüllý çömplétéd äll çöürsés änd réçéïvéd pässïng "
+"grädés för ä Pröféssïönäl Çértïfïçäté ïn {program_title} ä prögräm öfféréd "
"ßý {organizations}, ïn çölläßörätïön wïth {platform_name}. Ⱡ'σяєм ιρѕυм "
-"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
-"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
+"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη"
+"¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт #"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:167
msgid "recipient"
msgstr "réçïpïént Ⱡ'σяєм ιρѕυм ∂σł#"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:275
msgid ""
-"Issuer secret key. See: https://w3c-ccg.github.io/did-method-"
-"key/#ed25519-x25519"
+"Issuer secret key. See: https://w3c-ccg.github.io/did-method-key/#ed25519-"
+"x25519"
msgstr ""
-"Ìssüér séçrét kéý. Séé: https://w3ç-ççg.gïthüß.ïö/dïd-méthöd-"
-"kéý/#éd25519-x25519 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
+"Ìssüér séçrét kéý. Séé: https://w3ç-ççg.gïthüß.ïö/dïd-méthöd-kéý/#éd25519-"
+"x25519 Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
-#: apps/verifiable_credentials/issuance/status_list.py
+#: credentials/apps/verifiable_credentials/issuance/status_list.py:32
#, python-brace-format
msgid "Status List generation failed: [{issuer_id}]"
msgstr ""
"Stätüs Lïst générätïön fäïléd: [{issuer_id}] Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυ#"
-#: apps/verifiable_credentials/issuance/utils.py
+#: credentials/apps/verifiable_credentials/issuance/utils.py:54
msgid ""
"There are no enabled Issuance Configurations for some reason! At least one "
"must be always active."
@@ -813,31 +835,32 @@ msgstr ""
"Théré äré nö énäßléd Ìssüänçé Çönfïgürätïöns för sömé réäsön! Àt léäst öné "
"müst ßé älwäýs äçtïvé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: apps/verifiable_credentials/management/commands/create_default_issuer.py
+#: credentials/apps/verifiable_credentials/management/commands/create_default_issuer.py:26
#, python-brace-format
msgid "Verifiable Credentials feature is not enabled [{feature_name}]"
msgstr ""
"Vérïfïäßlé Çrédéntïäls féätüré ïs nöt énäßléd [{feature_name}] Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:84
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:94
msgid "Mandatory data is missing"
msgstr "Mändätörý dätä ïs mïssïng Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:89
msgid "Credential identifier must be valid UUID: ['credential_uuid']"
msgstr ""
"Çrédéntïäl ïdéntïfïér müst ßé välïd ÛÛÌD: ['çrédéntïäl_üüïd'] Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:101
#, python-format
msgid "No such user credential [%(credential_uuid)s]"
msgstr ""
"Nö süçh üsér çrédéntïäl [%(credential_uuid)s] Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢#"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:110
#, python-brace-format
msgid ""
"Provided storage backend ({storage_id}) isn't active. "
@@ -846,96 +869,98 @@ msgstr ""
"Prövïdéd störägé ßäçkénd ({storage_id}) ïsn't äçtïvé. "
"Störägés: {active_storages} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυ#"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:209
#, python-brace-format
msgid "Can't find an Issuer with such ID [{issuer_id}]"
msgstr ""
-"Çän't fïnd än Ìssüér wïth süçh ÌD [{issuer_id}] Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,"
-" ¢σηѕє¢тєтυя#"
+"Çän't fïnd än Ìssüér wïth süçh ÌD [{issuer_id}] Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
+"¢σηѕє¢тєтυя#"
-#: apps/verifiable_credentials/storages/learner_credential_wallet.py
+#: credentials/apps/verifiable_credentials/storages/learner_credential_wallet.py:39
msgid "Learner Credential Wallet"
msgstr "Léärnér Çrédéntïäl Wällét Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: templates/404.html
+#: credentials/templates/404.html:6 credentials/templates/404.html:11
msgid "Page Not Found"
msgstr "Pägé Nöt Föünd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: templates/500.html
+#: credentials/templates/500.html:6 credentials/templates/500.html:11
msgid "Server Error"
msgstr "Sérvér Érrör Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:7
msgid "Print or share your certificate"
msgstr "Prïnt ör shäré ýöür çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:9 credentials/templates/_actions.html:19
msgid "Share this certificate via Facebook"
msgstr ""
"Shäré thïs çértïfïçäté vïä Fäçéßöök Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:24
+#: credentials/templates/_actions.html:32
msgid "Tweet this certificate"
msgstr "Twéét thïs çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:38
msgid "Add to LinkedIn profile"
msgstr "Àdd tö LïnkédÌn pröfïlé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:47
msgid "Add this certificate to your LinkedIn profile"
msgstr ""
"Àdd thïs çértïfïçäté tö ýöür LïnkédÌn pröfïlé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:52
msgid "Print"
msgstr "Prïnt Ⱡ'σяєм ιρѕ#"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:58
msgid "Print this certificate"
msgstr "Prïnt thïs çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:7
msgid "Legal Policies"
msgstr "Légäl Pölïçïés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:11
msgid "Terms of Service & Honor Code"
msgstr "Térms öf Sérvïçé & Hönör Çödé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:16
msgid "Privacy Policy"
msgstr "Prïväçý Pölïçý Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:26
msgid ""
"All rights reserved except where noted. edX, Open edX and the edX and Open "
"edX logos are registered trademarks or trademarks of edX Inc."
msgstr ""
"Àll rïghts résérvéd éxçépt whéré nötéd. édX, Öpén édX änd thé édX änd Öpén "
"édX lögös äré régïstéréd trädémärks ör trädémärks öf édX Ìnç. Ⱡ'σяєм ιρѕυм "
-"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
-"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
+"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη"
+"¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ єѕт łαвσя#"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:36
msgid "Powered by"
msgstr "Pöwéréd ßý Ⱡ'σяєм ιρѕυм ∂σłσ#"
-#: templates/base.html templates/credentials/base.html
+#: credentials/templates/base.html:42
+#: credentials/templates/credentials/base.html:12
msgid "Skip to main content"
msgstr "Skïp tö mäïn çöntént Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: templates/credentials/base.html
+#: credentials/templates/credentials/base.html:25
#, python-format
msgid "Congratulations, %(user_name)s!"
msgstr "Çöngrätülätïöns, %(user_name)s! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: templates/credentials/base.html
+#: credentials/templates/credentials/base.html:32
#, python-format
msgid ""
"You worked hard to earn your certificate from %(platform_name)s — share it "
@@ -944,56 +969,55 @@ msgid ""
msgstr ""
"Ýöü wörkéd härd tö éärn ýöür çértïfïçäté fröm %(platform_name)s — shäré ït "
"wïth çölléägüés, frïénds, änd fämïlý tö gét thé wörd öüt äßöüt whät ýöü "
-"mästéréd ïn %(program_display_name)s. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт "
-"∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση "
-"υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ ¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє "
-"∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα"
-" ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι"
-" σƒƒι¢ια ∂єѕєяυηт мσłłιт αηι#"
-
-#: templates/credentials/edx_ace/common/base_body.html
+"mästéréd ïn %(program_display_name)s. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт "
+"∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση υłłαм"
+"¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ ¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη "
+"яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα "
+"ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι "
+"σƒƒι¢ια ∂єѕєяυηт мσłłιт αηι#"
+
+#: credentials/templates/credentials/edx_ace/common/base_body.html:33
#, python-format
msgid "Go to %(platform_name)s Home Page"
msgstr "Gö tö %(platform_name)s Hömé Pägé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
-#: templates/credentials/edx_ace/common/base_body.html
+#: credentials/templates/credentials/edx_ace/common/base_body.html:58
msgid "All rights reserved"
msgstr "Àll rïghts résérvéd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html:11
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:2
msgid "Hello"
msgstr "Héllö Ⱡ'σяєм ιρѕ#"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html:14
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:4
#, python-format
msgid ""
-"Congratulations on completing the %(program_title)s %(program_type)s "
-"Program!"
+"Congratulations on completing the %(program_title)s %(program_type)s Program!"
msgstr ""
"Çöngrätülätïöns ön çömplétïng thé %(program_title)s %(program_type)s "
"Prögräm! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html:18
#, python-format
msgid "Sincerely,
The %(platform_name)s Team"
msgstr ""
"Sïnçérélý,
Thé %(platform_name)s Téäm Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:6
msgid "Sincerely"
msgstr "Sïnçérélý Ⱡ'σяєм ιρѕυм ∂σł#"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:7
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:23
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:21
#, python-format
msgid "The %(platform_name)s Team"
msgstr "Thé %(platform_name)s Téäm Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/subject.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/subject.txt:3
#, python-format
msgid ""
"Congratulations for finishing your %(program_title)s %(program_type)s "
@@ -1002,19 +1026,18 @@ msgstr ""
"Çöngrätülätïöns för fïnïshïng ýöür %(program_title)s %(program_type)s "
"Prögräm! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:30
msgid "Supported by the following organizations"
msgstr ""
-"Süppörtéd ßý thé föllöwïng örgänïzätïöns Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
-"¢σηѕє¢тєтυя#"
+"Süppörtéd ßý thé föllöwïng örgänïzätïöns Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє"
+"¢тєтυя#"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:39
msgid "logo"
msgstr "lögö Ⱡ'σяєм ι#"
-#. Translators: This phrase is followed by a statement of the learner's
-#. achievement. e.g. 'has completed the course'
-#: templates/credentials/programs/base.html
+#. Translators: This phrase is followed by a statement of the learner's achievement. e.g. 'has completed the course'
+#: credentials/templates/credentials/programs/base.html:53
#, python-brace-format
msgid ""
"{start_span}This is to certify that{end_span} {start_strong} {user_name} "
@@ -1023,9 +1046,8 @@ msgstr ""
"{start_span}Thïs ïs tö çértïfý thät{end_span} {start_strong} {user_name} "
"{end_strong} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
-#. Translators: organization_name is the display name for the provided
-#. organization e.g (e.g., Test Organization).
-#: templates/credentials/programs/base.html
+#. Translators: organization_name is the display name for the provided organization e.g (e.g., Test Organization).
+#: credentials/templates/credentials/programs/base.html:67
#, python-format
msgid ""
"a program offered by %(org_name_string)s, in collaboration with "
@@ -1034,50 +1056,50 @@ msgstr ""
"ä prögräm öfféréd ßý %(org_name_string)s, ïn çölläßörätïön wïth "
"%(platform_name)s. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:75
msgid "Noted by"
msgstr "Nötéd ßý Ⱡ'σяєм ιρѕυм ∂#"
#. Translators: This phrase appears on certificates to show the issue date
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:109
#, python-brace-format
msgid "Issued {month} {year}"
msgstr "Ìssüéd {month} {year} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:115
msgid "Valid Certificate ID"
msgstr "Välïd Çértïfïçäté ÌD Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:121
msgid "Effort"
msgstr "Éffört Ⱡ'σяєм ιρѕυ#"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:124
#, python-format
msgid "%(num_hours)s hour"
msgid_plural "%(num_hours)s hours"
msgstr[0] "%(num_hours)s höür Ⱡ'σяєм ιρѕυм ∂#"
msgstr[1] "%(num_hours)s höürs Ⱡ'σяєм ιρѕυм ∂σł#"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:138
#, python-brace-format
msgid ""
-"For tips and tricks on printing your certificate, view the {start_anchor}Web"
-" Certificates help documentation{end_anchor}."
+"For tips and tricks on printing your certificate, view the {start_anchor}Web "
+"Certificates help documentation{end_anchor}."
msgstr ""
-"För tïps änd trïçks ön prïntïng ýöür çértïfïçäté, vïéw thé {start_anchor}Wéß"
-" Çértïfïçätés hélp döçüméntätïön{end_anchor}. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмє#"
+"För tïps änd trïçks ön prïntïng ýöür çértïfïçäté, vïéw thé {start_anchor}Wéß "
+"Çértïfïçätés hélp döçüméntätïön{end_anchor}. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмє#"
-#: templates/management.html
+#: credentials/templates/management.html:9
msgid "Management View"
msgstr "Mänägémént Vïéw Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
-#: templates/management.html
+#: credentials/templates/management.html:23
msgid "Clear cache"
msgstr "Çléär çäçhé Ⱡ'σяєм ιρѕυм ∂σłσя #"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:5
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:5
#, python-format
msgid ""
"%(user_full_name)s has sent an updated program record for %(program_name)s."
@@ -1085,8 +1107,8 @@ msgstr ""
"%(user_full_name)s häs sént än üpdätéd prögräm réçörd för %(program_name)s. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:7
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:7
#, python-format
msgid ""
"%(user_full_name)s has sent their completed program record for "
@@ -1095,8 +1117,8 @@ msgstr ""
"%(user_full_name)s häs sént théïr çömplétéd prögräm réçörd för "
"%(program_name)s. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:11
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:11
#, python-format
msgid ""
"%(user_full_name)s has sent their partially completed program record for "
@@ -1105,8 +1127,8 @@ msgstr ""
"%(user_full_name)s häs sént théïr pärtïällý çömplétéd prögräm réçörd för "
"%(program_name)s. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:14
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:14
#, python-format
msgid ""
"%(user_full_name)s would like to apply for credit in the %(pathway_name)s."
@@ -1114,8 +1136,8 @@ msgstr ""
"%(user_full_name)s wöüld lïké tö äpplý för çrédït ïn thé %(pathway_name)s. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:16
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:16
#, python-format
msgid ""
"Please view or download %(user_full_name)s’s public program record to "
@@ -1124,30 +1146,30 @@ msgstr ""
"Pléäsé vïéw ör döwnlöäd %(user_full_name)s’s püßlïç prögräm réçörd tö "
"détérmïné théïr çrédït élïgïßïlïtý stätüs. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:19
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:18
msgid "View Program Record"
msgstr "Vïéw Prögräm Réçörd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:20
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:19
msgid "Download Record (CSV)"
msgstr "Döwnlöäd Réçörd (ÇSV) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
-#: templates/records/edx_ace/programcreditrequest/email/subject.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/subject.txt:4
#, python-format
msgid "%(program_name)s Updated Credit Request for %(user_full_name)s"
msgstr ""
"%(program_name)s Ûpdätéd Çrédït Réqüést för %(user_full_name)s Ⱡ'σяєм ιρѕυм "
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
-#: templates/records/edx_ace/programcreditrequest/email/subject.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/subject.txt:6
#, python-format
msgid "%(program_name)s Credit Request for %(user_full_name)s"
msgstr ""
"%(program_name)s Çrédït Réqüést för %(user_full_name)s Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕ#"
-#: urls.py
+#: credentials/urls.py:39
msgid "Credentials Administration"
msgstr "Çrédéntïäls Àdmïnïsträtïön Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
diff --git a/credentials/conf/locale/rtl/LC_MESSAGES/django.mo b/credentials/conf/locale/rtl/LC_MESSAGES/django.mo
index ef95f7d353..9a1e996c2a 100644
Binary files a/credentials/conf/locale/rtl/LC_MESSAGES/django.mo and b/credentials/conf/locale/rtl/LC_MESSAGES/django.mo differ
diff --git a/credentials/conf/locale/rtl/LC_MESSAGES/django.po b/credentials/conf/locale/rtl/LC_MESSAGES/django.po
index 827b67d035..297beb85d7 100644
--- a/credentials/conf/locale/rtl/LC_MESSAGES/django.po
+++ b/credentials/conf/locale/rtl/LC_MESSAGES/django.po
@@ -6,8 +6,8 @@
msgid ""
msgstr ""
"Project-Id-Version: 0.1a\n"
-"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
-"POT-Creation-Date: 2024-05-27 10:13+0000\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2024-05-31 13:57+0000\n"
"PO-Revision-Date: 2024-05-27 10:13:41.472759\n"
"Last-Translator: \n"
"Language-Team: openedx-translation \n"
@@ -17,113 +17,129 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:72 credentials/apps/badges/admin.py:117
msgid "No rules specified."
msgstr "Nø ɹnlǝs sdǝɔᴉɟᴉǝd."
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:178
msgid "Badge templates were successfully updated."
msgstr "Ƀɐdƃǝ ʇǝɯdlɐʇǝs ʍǝɹǝ snɔɔǝssɟnllʎ nddɐʇǝd."
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:180
msgid "API key"
msgstr "ȺⱣƗ ʞǝʎ"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:186
msgid "Pre-configured from the environment."
msgstr "Ᵽɹǝ-ɔønɟᴉƃnɹǝd ɟɹøɯ ʇɥǝ ǝnʌᴉɹønɯǝnʇ."
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:248
+#, fuzzy
+#| msgid ""
+#| "\n"
+#| " WARNING: avoid configuration updates on activated "
+#| "badges.\n"
+#| " Active badge templates are continuously processed and "
+#| "learners may already have partial progress on them.\n"
+#| " Any changes in badge template requirements (including "
+#| "data rules) will affect learners' experience!\n"
+#| " "
msgid ""
"\n"
-" WARNING: avoid configuration updates on activated badges.\n"
-" Active badge templates are continuously processed and learners may already have partial progress on them.\n"
-" Any changes in badge template requirements (including data rules) will affect learners' experience!\n"
+" WARNING: avoid configuration updates on activated "
+"badges.\n"
+" Active badge templates are continuously processed and "
+"learners may already have progress on them.\n"
+" Any changes in badge template requirements (including "
+"data rules) will affect learners' experience!\n"
" "
msgstr ""
"\n"
-" WȺɌNƗNǤ: ɐʌøᴉd ɔønɟᴉƃnɹɐʇᴉøn nddɐʇǝs øn ɐɔʇᴉʌɐʇǝd bɐdƃǝs.\n"
-" Ⱥɔʇᴉʌǝ bɐdƃǝ ʇǝɯdlɐʇǝs ɐɹǝ ɔønʇᴉnnønslʎ dɹøɔǝssǝd ɐnd lǝɐɹnǝɹs ɯɐʎ ɐlɹǝɐdʎ ɥɐʌǝ dɐɹʇᴉɐl dɹøƃɹǝss øn ʇɥǝɯ.\n"
-" Ⱥnʎ ɔɥɐnƃǝs ᴉn bɐdƃǝ ʇǝɯdlɐʇǝ ɹǝbnᴉɹǝɯǝnʇs (ᴉnɔlndᴉnƃ dɐʇɐ ɹnlǝs) ʍᴉll ɐɟɟǝɔʇ lǝɐɹnǝɹs' ǝxdǝɹᴉǝnɔǝ!\n"
+" WȺɌNƗNǤ: ɐʌøᴉd ɔønɟᴉƃnɹɐʇᴉøn nddɐʇǝs øn ɐɔʇᴉʌɐʇǝd "
+"bɐdƃǝs.\n"
+" Ⱥɔʇᴉʌǝ bɐdƃǝ ʇǝɯdlɐʇǝs ɐɹǝ ɔønʇᴉnnønslʎ dɹøɔǝssǝd ɐnd "
+"lǝɐɹnǝɹs ɯɐʎ ɐlɹǝɐdʎ ɥɐʌǝ dɐɹʇᴉɐl dɹøƃɹǝss øn ʇɥǝɯ.\n"
+" Ⱥnʎ ɔɥɐnƃǝs ᴉn bɐdƃǝ ʇǝɯdlɐʇǝ ɹǝbnᴉɹǝɯǝnʇs (ᴉnɔlndᴉnƃ "
+"dɐʇɐ ɹnlǝs) ʍᴉll ɐɟɟǝɔʇ lǝɐɹnǝɹs' ǝxdǝɹᴉǝnɔǝ!\n"
" "
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:297
msgid "Active badge template cannot be deleted."
msgstr "Ⱥɔʇᴉʌǝ bɐdƃǝ ʇǝɯdlɐʇǝ ɔɐnnøʇ bǝ dǝlǝʇǝd."
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:307
msgid "Active badge templates cannot be deleted."
msgstr "Ⱥɔʇᴉʌǝ bɐdƃǝ ʇǝɯdlɐʇǝs ɔɐnnøʇ bǝ dǝlǝʇǝd."
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:319
msgid "icon"
msgstr "ᴉɔøn"
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:332
msgid "Active badge template must have at least one requirement."
msgstr "Ⱥɔʇᴉʌǝ bɐdƃǝ ʇǝɯdlɐʇǝ ɯnsʇ ɥɐʌǝ ɐʇ lǝɐsʇ ønǝ ɹǝbnᴉɹǝɯǝnʇ."
-#: apps/badges/admin.py
+#: credentials/apps/badges/admin.py:391 credentials/apps/badges/admin.py:448
msgid "badge template"
msgstr "bɐdƃǝ ʇǝɯdlɐʇǝ"
-#: apps/badges/admin_forms.py
+#: credentials/apps/badges/admin_forms.py:48
msgid "You can't provide an API key for a configured organization."
msgstr "Ɏøn ɔɐn'ʇ dɹøʌᴉdǝ ɐn ȺⱣƗ ʞǝʎ ɟøɹ ɐ ɔønɟᴉƃnɹǝd øɹƃɐnᴉzɐʇᴉøn."
-#: apps/badges/admin_forms.py
+#: credentials/apps/badges/admin_forms.py:98
msgid "All requirements must belong to the same template."
msgstr "Ⱥll ɹǝbnᴉɹǝɯǝnʇs ɯnsʇ bǝlønƃ ʇø ʇɥǝ sɐɯǝ ʇǝɯdlɐʇǝ."
-#: apps/badges/admin_forms.py
+#: credentials/apps/badges/admin_forms.py:141
msgid "Value must be a boolean."
msgstr "Vɐlnǝ ɯnsʇ bǝ ɐ bøølǝɐn."
-#: apps/badges/issuers.py
+#: credentials/apps/badges/issuers.py:136
msgid "Open edX internal user credential was revoked"
msgstr "Ødǝn ǝdX ᴉnʇǝɹnɐl nsǝɹ ɔɹǝdǝnʇᴉɐl ʍɐs ɹǝʌøʞǝd"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:37
msgid "Put your Credly Organization ID here."
msgstr "Ᵽnʇ ʎønɹ Ȼɹǝdlʎ Øɹƃɐnᴉzɐʇᴉøn ƗĐ ɥǝɹǝ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:40
msgid "Credly API shared secret for Credly Organization."
msgstr "Ȼɹǝdlʎ ȺⱣƗ sɥɐɹǝd sǝɔɹǝʇ ɟøɹ Ȼɹǝdlʎ Øɹƃɐnᴉzɐʇᴉøn."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:47
msgid "Verbose name for Credly Organization."
msgstr "Vǝɹbøsǝ nɐɯǝ ɟøɹ Ȼɹǝdlʎ Øɹƃɐnᴉzɐʇᴉøn."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:87
msgid "Unique badge template ID."
msgstr "Ʉnᴉbnǝ bɐdƃǝ ʇǝɯdlɐʇǝ ƗĐ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:88
msgid "Badge template name."
msgstr "Ƀɐdƃǝ ʇǝɯdlɐʇǝ nɐɯǝ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:89
msgid "Badge template description."
msgstr "Ƀɐdƃǝ ʇǝɯdlɐʇǝ dǝsɔɹᴉdʇᴉøn."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:91
msgid "Badge template type."
msgstr "Ƀɐdƃǝ ʇǝɯdlɐʇǝ ʇʎdǝ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:94
msgid "Credly badge template state (auto-managed)."
msgstr "Ȼɹǝdlʎ bɐdƃǝ ʇǝɯdlɐʇǝ sʇɐʇǝ (ɐnʇø-ɯɐnɐƃǝd)."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:143
msgid "Credly Organization - template owner."
msgstr "Ȼɹǝdlʎ Øɹƃɐnᴉzɐʇᴉøn - ʇǝɯdlɐʇǝ øʍnǝɹ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:172
msgid "Badge template this requirement serves for."
msgstr "Ƀɐdƃǝ ʇǝɯdlɐʇǝ ʇɥᴉs ɹǝbnᴉɹǝɯǝnʇ sǝɹʌǝs ɟøɹ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:178
msgid ""
"Public signal type. Available events are configured in \"BADGES_CONFIG\" "
"setting. The crucial aspect for event to carry UserData in its payload."
@@ -131,299 +147,309 @@ msgstr ""
"Ᵽnblᴉɔ sᴉƃnɐl ʇʎdǝ. Ⱥʌɐᴉlɐblǝ ǝʌǝnʇs ɐɹǝ ɔønɟᴉƃnɹǝd ᴉn \"ɃȺĐǤɆS_ȻØNFƗǤ\" "
"sǝʇʇᴉnƃ. Ŧɥǝ ɔɹnɔᴉɐl ɐsdǝɔʇ ɟøɹ ǝʌǝnʇ ʇø ɔɐɹɹʎ ɄsǝɹĐɐʇɐ ᴉn ᴉʇs dɐʎløɐd."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:182
msgid "Provide more details if needed."
msgstr "Ᵽɹøʌᴉdǝ ɯøɹǝ dǝʇɐᴉls ᴉɟ nǝǝdǝd."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:188
+#, fuzzy
+#| msgid ""
+#| "Optional. Put requirements into the same arbitrary Group ID to make them "
+#| "interchangeable (OR processing logic applies)."
msgid ""
-"Optional. Put requirements into the same arbitrary Group ID to make them "
-"interchangeable (OR processing logic applies)."
+"Optional. Group requirements together using the same Group ID for "
+"interchangeable (OR processing logic)."
msgstr ""
"Ødʇᴉønɐl. Ᵽnʇ ɹǝbnᴉɹǝɯǝnʇs ᴉnʇø ʇɥǝ sɐɯǝ ɐɹbᴉʇɹɐɹʎ Ǥɹønd ƗĐ ʇø ɯɐʞǝ ʇɥǝɯ "
"ᴉnʇǝɹɔɥɐnƃǝɐblǝ (ØɌ dɹøɔǝssᴉnƃ løƃᴉɔ ɐddlᴉǝs)."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:190 credentials/apps/badges/models.py:544
+msgid "group"
+msgstr "ƃɹønd"
+
+#: credentials/apps/badges/models.py:292
msgid ""
-"Public signal's data payload nested property path, e.g: "
-"\"user.pii.username\"."
+"Public signal's data payload nested property path, e.g: \"user.pii.username"
+"\"."
msgstr ""
-"Ᵽnblᴉɔ sᴉƃnɐl's dɐʇɐ dɐʎløɐd nǝsʇǝd dɹødǝɹʇʎ dɐʇɥ, ǝ.ƃ: "
-"\"nsǝɹ.dᴉᴉ.nsǝɹnɐɯǝ\"."
+"Ᵽnblᴉɔ sᴉƃnɐl's dɐʇɐ dɐʎløɐd nǝsʇǝd dɹødǝɹʇʎ dɐʇɥ, ǝ.ƃ: \"nsǝɹ.dᴉᴉ.nsǝɹnɐɯǝ"
+"\"."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:293
msgid "key path"
msgstr "ʞǝʎ dɐʇɥ"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:299
msgid ""
-"Expected value comparison operator. "
-"https://docs.python.org/3/library/operator.html"
+"Expected value comparison operator. https://docs.python.org/3/library/"
+"operator.html"
msgstr ""
-"Ɇxdǝɔʇǝd ʌɐlnǝ ɔøɯdɐɹᴉsøn ødǝɹɐʇøɹ. "
-"ɥʇʇds://døɔs.dʎʇɥøn.øɹƃ/3/lᴉbɹɐɹʎ/ødǝɹɐʇøɹ.ɥʇɯl"
+"Ɇxdǝɔʇǝd ʌɐlnǝ ɔøɯdɐɹᴉsøn ødǝɹɐʇøɹ. ɥʇʇds://døɔs.dʎʇɥøn.øɹƃ/3/lᴉbɹɐɹʎ/"
+"ødǝɹɐʇøɹ.ɥʇɯl"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:303
msgid "Expected value for the nested property, e.g: \"cucumber1997\"."
msgstr "Ɇxdǝɔʇǝd ʌɐlnǝ ɟøɹ ʇɥǝ nǝsʇǝd dɹødǝɹʇʎ, ǝ.ƃ: \"ɔnɔnɯbǝɹ1997\"."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:304
msgid "expected value"
msgstr "ǝxdǝɔʇǝd ʌɐlnǝ"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:363
msgid "Parent requirement for this data rule."
msgstr "Ᵽɐɹǝnʇ ɹǝbnᴉɹǝɯǝnʇ ɟøɹ ʇɥᴉs dɐʇɐ ɹnlǝ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:388
msgid "Badge template this penalty serves for."
msgstr "Ƀɐdƃǝ ʇǝɯdlɐʇǝ ʇɥᴉs dǝnɐlʇʎ sǝɹʌǝs ɟøɹ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:394
msgid ""
-"Public signal type. Use namespaced types, e.g: "
-"\"org.openedx.learning.student.registration.completed.v1\""
+"Public signal type. Use namespaced types, e.g: \"org.openedx.learning."
+"student.registration.completed.v1\""
msgstr ""
-"Ᵽnblᴉɔ sᴉƃnɐl ʇʎdǝ. Ʉsǝ nɐɯǝsdɐɔǝd ʇʎdǝs, ǝ.ƃ: "
-"\"øɹƃ.ødǝnǝdx.lǝɐɹnᴉnƃ.sʇndǝnʇ.ɹǝƃᴉsʇɹɐʇᴉøn.ɔøɯdlǝʇǝd.ʌ1\""
+"Ᵽnblᴉɔ sᴉƃnɐl ʇʎdǝ. Ʉsǝ nɐɯǝsdɐɔǝd ʇʎdǝs, ǝ.ƃ: \"øɹƃ.ødǝnǝdx.lǝɐɹnᴉnƃ."
+"sʇndǝnʇ.ɹǝƃᴉsʇɹɐʇᴉøn.ɔøɯdlǝʇǝd.ʌ1\""
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:399
msgid "Badge requirements for which this penalty is defined."
msgstr "Ƀɐdƃǝ ɹǝbnᴉɹǝɯǝnʇs ɟøɹ ʍɥᴉɔɥ ʇɥᴉs dǝnɐlʇʎ ᴉs dǝɟᴉnǝd."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:403
msgid "Badge penalties"
msgstr "Ƀɐdƃǝ dǝnɐlʇᴉǝs"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:437
msgid "Parent penalty for this data rule."
msgstr "Ᵽɐɹǝnʇ dǝnɐlʇʎ ɟøɹ ʇɥᴉs dɐʇɐ ɹnlǝ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:469
msgid "badge progress records"
msgstr "bɐdƃǝ dɹøƃɹǝss ɹǝɔøɹds"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:543
msgid "Group ID for the requirement."
msgstr "Ǥɹønd ƗĐ ɟøɹ ʇɥǝ ɹǝbnᴉɹǝɯǝnʇ."
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:573
msgid "Credly badge issuing state"
msgstr "Ȼɹǝdlʎ bɐdƃǝ ᴉssnᴉnƃ sʇɐʇǝ"
-#: apps/badges/models.py
+#: credentials/apps/badges/models.py:581
msgid "Credly service badge identifier"
msgstr "Ȼɹǝdlʎ sǝɹʌᴉɔǝ bɐdƃǝ ᴉdǝnʇᴉɟᴉǝɹ"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:20
msgid "Activate selected entries"
msgstr "Ⱥɔʇᴉʌɐʇǝ sǝlǝɔʇǝd ǝnʇɹᴉǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:28
#, python-brace-format
msgid "1 {model_name} entry was successfully activated."
msgstr "1 {model_name} ǝnʇɹʎ ʍɐs snɔɔǝssɟnllʎ ɐɔʇᴉʌɐʇǝd."
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:30
#, python-brace-format
msgid "{count} {model_name} entries were successfully activated."
msgstr "{count} {model_name} ǝnʇɹᴉǝs ʍǝɹǝ snɔɔǝssɟnllʎ ɐɔʇᴉʌɐʇǝd."
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:34
msgid "Deactivate selected entries"
msgstr "Đǝɐɔʇᴉʌɐʇǝ sǝlǝɔʇǝd ǝnʇɹᴉǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:42
#, python-brace-format
msgid "1 {model_name} entry was successfully deactivated."
msgstr "1 {model_name} ǝnʇɹʎ ʍɐs snɔɔǝssɟnllʎ dǝɐɔʇᴉʌɐʇǝd."
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:44
#, python-brace-format
msgid "{count} {model_name} entries were successfully deactivated."
msgstr "{count} {model_name} ǝnʇɹᴉǝs ʍǝɹǝ snɔɔǝssɟnllʎ dǝɐɔʇᴉʌɐʇǝd."
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:48
msgid "Add is_staff to selected entries"
msgstr "Ⱥdd ᴉs_sʇɐɟɟ ʇø sǝlǝɔʇǝd ǝnʇɹᴉǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:56 credentials/apps/core/admin.py:70
+#: credentials/apps/core/admin.py:84 credentials/apps/core/admin.py:103
#, python-brace-format
msgid "1 {model_name} entry was successfully changed."
msgstr "1 {model_name} ǝnʇɹʎ ʍɐs snɔɔǝssɟnllʎ ɔɥɐnƃǝd."
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:58 credentials/apps/core/admin.py:72
+#: credentials/apps/core/admin.py:86 credentials/apps/core/admin.py:105
#, python-brace-format
msgid "{count} {model_name} entries were successfully changed."
msgstr "{count} {model_name} ǝnʇɹᴉǝs ʍǝɹǝ snɔɔǝssɟnllʎ ɔɥɐnƃǝd."
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:62
msgid "Remove is_staff from selected entries"
msgstr "Ɍǝɯøʌǝ ᴉs_sʇɐɟɟ ɟɹøɯ sǝlǝɔʇǝd ǝnʇɹᴉǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:76
msgid "Add is_superuser to selected entries"
msgstr "Ⱥdd ᴉs_sndǝɹnsǝɹ ʇø sǝlǝɔʇǝd ǝnʇɹᴉǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:90
msgid "Remove is_superuser from selected entries"
msgstr "Ɍǝɯøʌǝ ᴉs_sndǝɹnsǝɹ ɟɹøɯ sǝlǝɔʇǝd ǝnʇɹᴉǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:126
msgid "Personal info"
msgstr "Ᵽǝɹsønɐl ᴉnɟø"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:127
msgid "Permissions"
msgstr "Ᵽǝɹɯᴉssᴉøns"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:128
msgid "Important dates"
msgstr "Ɨɯdøɹʇɐnʇ dɐʇǝs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:155
msgid "URLs"
msgstr "ɄɌŁs"
-#: apps/core/admin.py
+#: credentials/apps/core/admin.py:170
msgid "Social Sharing"
msgstr "Søɔᴉɐl Sɥɐɹᴉnƃ"
-#: apps/core/forms.py
+#: credentials/apps/core/forms.py:12
msgid "A Facebook app ID is required to enable Facebook sharing."
msgstr "Ⱥ Fɐɔǝbøøʞ ɐdd ƗĐ ᴉs ɹǝbnᴉɹǝd ʇø ǝnɐblǝ Fɐɔǝbøøʞ sɥɐɹᴉnƃ."
-#: apps/core/models.py
+#: credentials/apps/core/models.py:24
msgid "Platform Name"
msgstr "Ᵽlɐʇɟøɹɯ Nɐɯǝ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:25
msgid "Name of your Open edX platform"
msgstr "Nɐɯǝ øɟ ʎønɹ Ødǝn ǝdX dlɐʇɟøɹɯ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:31
msgid "Segment Key"
msgstr "Sǝƃɯǝnʇ Ꝁǝʎ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:31
msgid "Segment write/API key."
msgstr "Sǝƃɯǝnʇ ʍɹᴉʇǝ/ȺⱣƗ ʞǝʎ."
-#: apps/core/models.py
+#: credentials/apps/core/models.py:34
msgid "Theme Name"
msgstr "Ŧɥǝɯǝ Nɐɯǝ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:35
msgid ""
"Name of of the theme to use for this site. This value should be lower-cased."
msgstr ""
"Nɐɯǝ øɟ øɟ ʇɥǝ ʇɥǝɯǝ ʇø nsǝ ɟøɹ ʇɥᴉs sᴉʇǝ. Ŧɥᴉs ʌɐlnǝ sɥønld bǝ løʍǝɹ-ɔɐsǝd."
-#: apps/core/models.py
+#: credentials/apps/core/models.py:48
msgid "LMS base url for custom site"
msgstr "ŁMS bɐsǝ nɹl ɟøɹ ɔnsʇøɯ sᴉʇǝ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:49
msgid "Root URL of this site's LMS (e.g. https://courses.stage.edx.org)"
msgstr "Ɍøøʇ ɄɌŁ øɟ ʇɥᴉs sᴉʇǝ's ŁMS (ǝ.ƃ. ɥʇʇds://ɔønɹsǝs.sʇɐƃǝ.ǝdx.øɹƃ)"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:54
msgid "Catalog API URL"
msgstr "Ȼɐʇɐløƃ ȺⱣƗ ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:55
msgid "Root URL of the Catalog API (e.g. https://api.edx.org/catalog/v1/)"
msgstr "Ɍøøʇ ɄɌŁ øɟ ʇɥǝ Ȼɐʇɐløƃ ȺⱣƗ (ǝ.ƃ. ɥʇʇds://ɐdᴉ.ǝdx.øɹƃ/ɔɐʇɐløƃ/ʌ1/)"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:60
msgid "Terms of Service URL"
msgstr "Ŧǝɹɯs øɟ Sǝɹʌᴉɔǝ ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:65
msgid "Privacy Policy URL"
msgstr "Ᵽɹᴉʌɐɔʎ Ᵽølᴉɔʎ ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:70
msgid "Homepage URL"
msgstr "Ħøɯǝdɐƃǝ ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:75
msgid "Company Name"
msgstr "Ȼøɯdɐnʎ Nɐɯǝ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:81
msgid "Verified Certificate URL"
msgstr "Vǝɹᴉɟᴉǝd Ȼǝɹʇᴉɟᴉɔɐʇǝ ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:87
msgid "Certificate Help URL"
msgstr "Ȼǝɹʇᴉɟᴉɔɐʇǝ Ħǝld ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:88
msgid "URL of page for questions about certificates"
msgstr "ɄɌŁ øɟ dɐƃǝ ɟøɹ bnǝsʇᴉøns ɐbønʇ ɔǝɹʇᴉɟᴉɔɐʇǝs"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:93
msgid "Enable Learner Records"
msgstr "Ɇnɐblǝ Łǝɐɹnǝɹ Ɍǝɔøɹds"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:94
msgid "Enable the Records feature. The LMS has a similar setting."
msgstr "Ɇnɐblǝ ʇɥǝ Ɍǝɔøɹds ɟǝɐʇnɹǝ. Ŧɥǝ ŁMS ɥɐs ɐ sᴉɯᴉlɐɹ sǝʇʇᴉnƃ."
-#: apps/core/models.py
+#: credentials/apps/core/models.py:98
msgid "Learner Records Help URL"
msgstr "Łǝɐɹnǝɹ Ɍǝɔøɹds Ħǝld ɄɌŁ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:99
msgid "URL of page for questions about Learner Records"
msgstr "ɄɌŁ øɟ dɐƃǝ ɟøɹ bnǝsʇᴉøns ɐbønʇ Łǝɐɹnǝɹ Ɍǝɔøɹds"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:105
msgid "Facebook App ID"
msgstr "Fɐɔǝbøøʞ Ⱥdd ƗĐ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:106
msgid "Facebook app ID used for sharing"
msgstr "Fɐɔǝbøøʞ ɐdd ƗĐ nsǝd ɟøɹ sɥɐɹᴉnƃ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:112
msgid "Twitter Username"
msgstr "Ŧʍᴉʇʇǝɹ Ʉsǝɹnɐɯǝ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:113
msgid "Twitter username included in tweeted credentials. Do NOT include @."
msgstr "Ŧʍᴉʇʇǝɹ nsǝɹnɐɯǝ ᴉnɔlndǝd ᴉn ʇʍǝǝʇǝd ɔɹǝdǝnʇᴉɐls. Đø NØŦ ᴉnɔlndǝ @."
-#: apps/core/models.py
+#: credentials/apps/core/models.py:119
msgid "Enable Facebook sharing"
msgstr "Ɇnɐblǝ Fɐɔǝbøøʞ sɥɐɹᴉnƃ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:119
msgid "Enable sharing via Facebook"
msgstr "Ɇnɐblǝ sɥɐɹᴉnƃ ʌᴉɐ Fɐɔǝbøøʞ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:122
msgid "Enable LinkedIn sharing"
msgstr "Ɇnɐblǝ ŁᴉnʞǝdƗn sɥɐɹᴉnƃ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:122
msgid "Enable sharing via LinkedIn"
msgstr "Ɇnɐblǝ sɥɐɹᴉnƃ ʌᴉɐ ŁᴉnʞǝdƗn"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:125
msgid "Enable Twitter sharing"
msgstr "Ɇnɐblǝ Ŧʍᴉʇʇǝɹ sɥɐɹᴉnƃ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:125
msgid "Enable sharing via Twitter"
msgstr "Ɇnɐblǝ sɥɐɹᴉnƃ ʌᴉɐ Ŧʍᴉʇʇǝɹ"
-#: apps/core/models.py
+#: credentials/apps/core/models.py:202
msgid "Full Name"
msgstr "Fnll Nɐɯǝ"
-#: apps/credentials/forms.py
+#: credentials/apps/credentials/forms.py:48
msgid ""
"All authoring organizations of the program MUST have a certificate image "
"defined!"
@@ -431,37 +457,36 @@ msgstr ""
"Ⱥll ɐnʇɥøɹᴉnƃ øɹƃɐnᴉzɐʇᴉøns øɟ ʇɥǝ dɹøƃɹɐɯ MɄSŦ ɥɐʌǝ ɐ ɔǝɹʇᴉɟᴉɔɐʇǝ ᴉɯɐƃǝ "
"dǝɟᴉnǝd!"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:57
msgid "The image file size must be less than 250KB."
msgstr "Ŧɥǝ ᴉɯɐƃǝ ɟᴉlǝ sᴉzǝ ɯnsʇ bǝ lǝss ʇɥɐn 250ꝀɃ."
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:67
msgid "Invalid course key."
msgstr "Ɨnʌɐlᴉd ɔønɹsǝ ʞǝʎ."
-#: apps/credentials/models.py
-msgid ""
-"Signatory organization name if its different from issuing organization."
+#: credentials/apps/credentials/models.py:98
+msgid "Signatory organization name if its different from issuing organization."
msgstr ""
"Sᴉƃnɐʇøɹʎ øɹƃɐnᴉzɐʇᴉøn nɐɯǝ ᴉɟ ᴉʇs dᴉɟɟǝɹǝnʇ ɟɹøɯ ᴉssnᴉnƃ øɹƃɐnᴉzɐʇᴉøn."
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:101
msgid "Image must be square PNG files. The file size should be under 250KB."
msgstr "Ɨɯɐƃǝ ɯnsʇ bǝ sbnɐɹǝ ⱣNǤ ɟᴉlǝs. Ŧɥǝ ɟᴉlǝ sᴉzǝ sɥønld bǝ nndǝɹ 250ꝀɃ."
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:165
msgid "awarded"
msgstr "ɐʍɐɹdǝd"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:166
msgid "revoked"
msgstr "ɹǝʌøʞǝd"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:184
msgid "URL at which the credential can be downloaded"
msgstr "ɄɌŁ ɐʇ ʍɥᴉɔɥ ʇɥǝ ɔɹǝdǝnʇᴉɐl ɔɐn bǝ døʍnløɐdǝd"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:216
msgid ""
"The certificate available date and time that is set in Studio and copied to "
"Credentials. This should be edited in Studio."
@@ -469,40 +494,39 @@ msgstr ""
"Ŧɥǝ ɔǝɹʇᴉɟᴉɔɐʇǝ ɐʌɐᴉlɐblǝ dɐʇǝ ɐnd ʇᴉɯǝ ʇɥɐʇ ᴉs sǝʇ ᴉn Sʇndᴉø ɐnd ɔødᴉǝd ʇø "
"Ȼɹǝdǝnʇᴉɐls. Ŧɥᴉs sɥønld bǝ ǝdᴉʇǝd ᴉn Sʇndᴉø."
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:269
msgid "Program UUID"
msgstr "Ᵽɹøƃɹɐɯ ɄɄƗĐ"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:282
msgid ""
-"Display the associated organization's name (e.g. ACME University) instead of"
-" its short name (e.g. ACMEx)"
+"Display the associated organization's name (e.g. ACME University) instead of "
+"its short name (e.g. ACMEx)"
msgstr ""
-"Đᴉsdlɐʎ ʇɥǝ ɐssøɔᴉɐʇǝd øɹƃɐnᴉzɐʇᴉøn's nɐɯǝ (ǝ.ƃ. ȺȻMɆ Ʉnᴉʌǝɹsᴉʇʎ) ᴉnsʇǝɐd øɟ"
-" ᴉʇs sɥøɹʇ nɐɯǝ (ǝ.ƃ. ȺȻMɆx)"
+"Đᴉsdlɐʎ ʇɥǝ ɐssøɔᴉɐʇǝd øɹƃɐnᴉzɐʇᴉøn's nɐɯǝ (ǝ.ƃ. ȺȻMɆ Ʉnᴉʌǝɹsᴉʇʎ) ᴉnsʇǝɐd øɟ "
+"ᴉʇs sɥøɹʇ nɐɯǝ (ǝ.ƃ. ȺȻMɆx)"
-#: apps/credentials/models.py
+#: credentials/apps/credentials/models.py:285
msgid "Use organization name"
msgstr "Ʉsǝ øɹƃɐnᴉzɐʇᴉøn nɐɯǝ"
-#: apps/credentials/views.py
+#: credentials/apps/credentials/views.py:63
#, python-brace-format
msgid "{first_org} and {second_org}"
msgstr "{first_org} ɐnd {second_org}"
-#: apps/credentials/views.py
+#: credentials/apps/credentials/views.py:67
#, python-brace-format
msgid "{series_of_orgs}, and {last_org}"
msgstr "{series_of_orgs}, ɐnd {last_org}"
-#: apps/credentials/views.py
+#: credentials/apps/credentials/views.py:123
#, python-brace-format
-msgid ""
-"I completed a course at {platform_name}. Take a look at my certificate:"
+msgid "I completed a course at {platform_name}. Take a look at my certificate:"
msgstr ""
"Ɨ ɔøɯdlǝʇǝd ɐ ɔønɹsǝ ɐʇ {platform_name}. Ŧɐʞǝ ɐ løøʞ ɐʇ ɯʎ ɔǝɹʇᴉɟᴉɔɐʇǝ:"
-#: apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html
+#: credentials/apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html:7
msgid ""
"successfully completed all courses and received passing grades for a "
"Professional Certificate in"
@@ -510,142 +534,142 @@ msgstr ""
"snɔɔǝssɟnllʎ ɔøɯdlǝʇǝd ɐll ɔønɹsǝs ɐnd ɹǝɔǝᴉʌǝd dɐssᴉnƃ ƃɹɐdǝs ɟøɹ ɐ "
"Ᵽɹøɟǝssᴉønɐl Ȼǝɹʇᴉɟᴉɔɐʇǝ ᴉn"
-#: apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html
+#: credentials/apps/credentials_theme_openedx/templates/openedx/credentials/programs/professional-certificate/certificate.html:11
msgid "Professional Certificate"
msgstr "Ᵽɹøɟǝssᴉønɐl Ȼǝɹʇᴉɟᴉɔɐʇǝ"
-#: apps/edx_django_extensions/views.py
+#: credentials/apps/edx_django_extensions/views.py:24
msgid "Cache cleared."
msgstr "Ȼɐɔɥǝ ɔlǝɐɹǝd."
-#: apps/edx_django_extensions/views.py
+#: credentials/apps/edx_django_extensions/views.py:26
#, python-brace-format
msgid "{action} is not a valid action."
msgstr "{action} ᴉs nøʇ ɐ ʌɐlᴉd ɐɔʇᴉøn."
-#: apps/records/api.py
+#: credentials/apps/records/api.py:230
msgid "N/A"
msgstr "N/Ⱥ"
-#: apps/records/models.py
+#: credentials/apps/records/models.py:76
msgid "sent"
msgstr "sǝnʇ"
-#: apps/records/models.py
+#: credentials/apps/records/models.py:77
msgid "other"
msgstr "øʇɥǝɹ"
-#: apps/records/models.py
+#: credentials/apps/records/models.py:94
msgid "User credit pathways can only be connected to credit pathways."
msgstr "Ʉsǝɹ ɔɹǝdᴉʇ dɐʇɥʍɐʎs ɔɐn ønlʎ bǝ ɔønnǝɔʇǝd ʇø ɔɹǝdᴉʇ dɐʇɥʍɐʎs."
-#: apps/records/views.py
+#: credentials/apps/records/views.py:119
msgid "Program Listing View"
msgstr "Ᵽɹøƃɹɐɯ Łᴉsʇᴉnƃ Vᴉǝʍ"
-#: apps/records/views.py
+#: credentials/apps/records/views.py:121
msgid ""
-"The following is a list of all active programs for which program records are"
-" being generated."
+"The following is a list of all active programs for which program records are "
+"being generated."
msgstr ""
-"Ŧɥǝ ɟølløʍᴉnƃ ᴉs ɐ lᴉsʇ øɟ ɐll ɐɔʇᴉʌǝ dɹøƃɹɐɯs ɟøɹ ʍɥᴉɔɥ dɹøƃɹɐɯ ɹǝɔøɹds ɐɹǝ"
-" bǝᴉnƃ ƃǝnǝɹɐʇǝd."
+"Ŧɥǝ ɟølløʍᴉnƃ ᴉs ɐ lᴉsʇ øɟ ɐll ɐɔʇᴉʌǝ dɹøƃɹɐɯs ɟøɹ ʍɥᴉɔɥ dɹøƃɹɐɯ ɹǝɔøɹds ɐɹǝ "
+"bǝᴉnƃ ƃǝnǝɹɐʇǝd."
-#: apps/verifiable_credentials/admin.py
+#: credentials/apps/verifiable_credentials/admin.py:15
msgid "Issuer ID"
msgstr "Ɨssnǝɹ ƗĐ"
-#: apps/verifiable_credentials/admin.py
+#: credentials/apps/verifiable_credentials/admin.py:75
msgid "At least one Issuer must be always enabled!"
msgstr "Ⱥʇ lǝɐsʇ ønǝ Ɨssnǝɹ ɯnsʇ bǝ ɐlʍɐʎs ǝnɐblǝd!"
-#: apps/verifiable_credentials/composition/open_badges.py
+#: credentials/apps/verifiable_credentials/composition/open_badges.py:59
msgid "Open Badges Specification v3.0"
msgstr "Ødǝn Ƀɐdƃǝs Sdǝɔᴉɟᴉɔɐʇᴉøn ʌ3.0"
-#: apps/verifiable_credentials/composition/open_badges.py
+#: credentials/apps/verifiable_credentials/composition/open_badges.py:100
msgid "Open Badges Specification v3.0.1"
msgstr "Ødǝn Ƀɐdƃǝs Sdǝɔᴉɟᴉɔɐʇᴉøn ʌ3.0.1"
-#: apps/verifiable_credentials/composition/status_list.py
-#: apps/verifiable_credentials/storages/status_list.py
+#: credentials/apps/verifiable_credentials/composition/status_list.py:100
+#: credentials/apps/verifiable_credentials/storages/status_list.py:17
msgid "Status List 2021"
msgstr "Sʇɐʇns Łᴉsʇ 2021"
-#: apps/verifiable_credentials/composition/verifiable_credentials.py
+#: credentials/apps/verifiable_credentials/composition/verifiable_credentials.py:21
msgid "Verifiable Credentials Data Model v1.1"
msgstr "Vǝɹᴉɟᴉɐblǝ Ȼɹǝdǝnʇᴉɐls Đɐʇɐ Mødǝl ʌ1.1"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:56
#, python-brace-format
msgid "Couldn't find such issuance line: [{issuance_uuid}]"
msgstr "Ȼønldn'ʇ ɟᴉnd snɔɥ ᴉssnɐnɔǝ lᴉnǝ: [{issuance_uuid}]"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:62
#, python-brace-format
msgid "Seems credential isn't active anymore: [{credential_id}]"
msgstr "Sǝǝɯs ɔɹǝdǝnʇᴉɐl ᴉsn'ʇ ɐɔʇᴉʌǝ ɐnʎɯøɹǝ: [{credential_id}]"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:99
msgid "Provided data didn't validate"
msgstr "Ᵽɹøʌᴉdǝd dɐʇɐ dᴉdn'ʇ ʌɐlᴉdɐʇǝ"
-#: apps/verifiable_credentials/issuance/main.py
+#: credentials/apps/verifiable_credentials/issuance/main.py:125
msgid "Issued verifiable credential can't be verified!"
msgstr "Ɨssnǝd ʌǝɹᴉɟᴉɐblǝ ɔɹǝdǝnʇᴉɐl ɔɐn'ʇ bǝ ʌǝɹᴉɟᴉǝd!"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:45
msgid "Related Open edX learner credential"
msgstr "Ɍǝlɐʇǝd Ødǝn ǝdX lǝɐɹnǝɹ ɔɹǝdǝnʇᴉɐl"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:47
msgid "Completeness indicator"
msgstr "Ȼøɯdlǝʇǝnǝss ᴉndᴉɔɐʇøɹ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:48
+#: credentials/apps/verifiable_credentials/issuance/models.py:273
msgid "Issuer DID"
msgstr "Ɨssnǝɹ ĐƗĐ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:49
msgid "Target storage identifier"
msgstr "Ŧɐɹƃǝʇ sʇøɹɐƃǝ ᴉdǝnʇᴉɟᴉǝɹ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:53
msgid "Verifiable credential subject DID"
msgstr "Vǝɹᴉɟᴉɐblǝ ɔɹǝdǝnʇᴉɐl snbɾǝɔʇ ĐƗĐ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:59
msgid "Verifiable credential specification to use"
msgstr "Vǝɹᴉɟᴉɐblǝ ɔɹǝdǝnʇᴉɐl sdǝɔᴉɟᴉɔɐʇᴉøn ʇø nsǝ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:66
msgid "Defines a position in the Status List sequence"
msgstr "Đǝɟᴉnǝs ɐ døsᴉʇᴉøn ᴉn ʇɥǝ Sʇɐʇns Łᴉsʇ sǝbnǝnɔǝ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:72
msgid "Keeps track on a corresponding user credential's status"
msgstr "Ꝁǝǝds ʇɹɐɔʞ øn ɐ ɔøɹɹǝsdøndᴉnƃ nsǝɹ ɔɹǝdǝnʇᴉɐl's sʇɐʇns"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:109
msgid "program certificate"
msgstr "dɹøƃɹɐɯ ɔǝɹʇᴉɟᴉɔɐʇǝ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:110
msgid "course certificate"
msgstr "ɔønɹsǝ ɔǝɹʇᴉɟᴉɔɐʇǝ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:123
#, python-brace-format
msgid "program certificate for passing a program {program_title}"
msgstr "dɹøƃɹɐɯ ɔǝɹʇᴉɟᴉɔɐʇǝ ɟøɹ dɐssᴉnƃ ɐ dɹøƃɹɐɯ {program_title}"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:136
#, python-brace-format
msgid ", with total {hours_of_effort} Hours of effort required to complete it"
-msgstr ""
-", ʍᴉʇɥ ʇøʇɐl {hours_of_effort} Ħønɹs øɟ ǝɟɟøɹʇ ɹǝbnᴉɹǝd ʇø ɔøɯdlǝʇǝ ᴉʇ"
+msgstr ", ʍᴉʇɥ ʇøʇɐl {hours_of_effort} Ħønɹs øɟ ǝɟɟøɹʇ ɹǝbnᴉɹǝd ʇø ɔøɯdlǝʇǝ ᴉʇ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:144
#, python-brace-format
msgid ""
"{credential_type} is granted on program {program_title} completion offered "
@@ -656,35 +680,35 @@ msgstr ""
"bʎ {organizations}, ᴉn ɔøllɐbøɹɐʇᴉøn ʍᴉʇɥ {platform_name}. Ŧɥǝ "
"{program_title} dɹøƃɹɐɯ ᴉnɔlndǝs {course_count} ɔønɹsǝ(s){effort_info}."
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:165
#, python-brace-format
msgid ""
-"{recipient_fullname} successfully completed all courses and received passing"
-" grades for a Professional Certificate in {program_title} a program offered "
+"{recipient_fullname} successfully completed all courses and received passing "
+"grades for a Professional Certificate in {program_title} a program offered "
"by {organizations}, in collaboration with {platform_name}."
msgstr ""
-"{recipient_fullname} snɔɔǝssɟnllʎ ɔøɯdlǝʇǝd ɐll ɔønɹsǝs ɐnd ɹǝɔǝᴉʌǝd dɐssᴉnƃ"
-" ƃɹɐdǝs ɟøɹ ɐ Ᵽɹøɟǝssᴉønɐl Ȼǝɹʇᴉɟᴉɔɐʇǝ ᴉn {program_title} ɐ dɹøƃɹɐɯ øɟɟǝɹǝd "
+"{recipient_fullname} snɔɔǝssɟnllʎ ɔøɯdlǝʇǝd ɐll ɔønɹsǝs ɐnd ɹǝɔǝᴉʌǝd dɐssᴉnƃ "
+"ƃɹɐdǝs ɟøɹ ɐ Ᵽɹøɟǝssᴉønɐl Ȼǝɹʇᴉɟᴉɔɐʇǝ ᴉn {program_title} ɐ dɹøƃɹɐɯ øɟɟǝɹǝd "
"bʎ {organizations}, ᴉn ɔøllɐbøɹɐʇᴉøn ʍᴉʇɥ {platform_name}."
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:167
msgid "recipient"
msgstr "ɹǝɔᴉdᴉǝnʇ"
-#: apps/verifiable_credentials/issuance/models.py
+#: credentials/apps/verifiable_credentials/issuance/models.py:275
msgid ""
-"Issuer secret key. See: https://w3c-ccg.github.io/did-method-"
-"key/#ed25519-x25519"
+"Issuer secret key. See: https://w3c-ccg.github.io/did-method-key/#ed25519-"
+"x25519"
msgstr ""
-"Ɨssnǝɹ sǝɔɹǝʇ ʞǝʎ. Sǝǝ: ɥʇʇds://ʍ3ɔ-ɔɔƃ.ƃᴉʇɥnb.ᴉø/dᴉd-ɯǝʇɥød-"
-"ʞǝʎ/#ǝd25519-x25519"
+"Ɨssnǝɹ sǝɔɹǝʇ ʞǝʎ. Sǝǝ: ɥʇʇds://ʍ3ɔ-ɔɔƃ.ƃᴉʇɥnb.ᴉø/dᴉd-ɯǝʇɥød-ʞǝʎ/#ǝd25519-"
+"x25519"
-#: apps/verifiable_credentials/issuance/status_list.py
+#: credentials/apps/verifiable_credentials/issuance/status_list.py:32
#, python-brace-format
msgid "Status List generation failed: [{issuer_id}]"
msgstr "Sʇɐʇns Łᴉsʇ ƃǝnǝɹɐʇᴉøn ɟɐᴉlǝd: [{issuer_id}]"
-#: apps/verifiable_credentials/issuance/utils.py
+#: credentials/apps/verifiable_credentials/issuance/utils.py:54
msgid ""
"There are no enabled Issuance Configurations for some reason! At least one "
"must be always active."
@@ -692,25 +716,26 @@ msgstr ""
"Ŧɥǝɹǝ ɐɹǝ nø ǝnɐblǝd Ɨssnɐnɔǝ Ȼønɟᴉƃnɹɐʇᴉøns ɟøɹ søɯǝ ɹǝɐsøn! Ⱥʇ lǝɐsʇ ønǝ "
"ɯnsʇ bǝ ɐlʍɐʎs ɐɔʇᴉʌǝ."
-#: apps/verifiable_credentials/management/commands/create_default_issuer.py
+#: credentials/apps/verifiable_credentials/management/commands/create_default_issuer.py:26
#, python-brace-format
msgid "Verifiable Credentials feature is not enabled [{feature_name}]"
msgstr "Vǝɹᴉɟᴉɐblǝ Ȼɹǝdǝnʇᴉɐls ɟǝɐʇnɹǝ ᴉs nøʇ ǝnɐblǝd [{feature_name}]"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:84
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:94
msgid "Mandatory data is missing"
msgstr "Mɐndɐʇøɹʎ dɐʇɐ ᴉs ɯᴉssᴉnƃ"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:89
msgid "Credential identifier must be valid UUID: ['credential_uuid']"
msgstr "Ȼɹǝdǝnʇᴉɐl ᴉdǝnʇᴉɟᴉǝɹ ɯnsʇ bǝ ʌɐlᴉd ɄɄƗĐ: ['ɔɹǝdǝnʇᴉɐl_nnᴉd']"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:101
#, python-format
msgid "No such user credential [%(credential_uuid)s]"
msgstr "Nø snɔɥ nsǝɹ ɔɹǝdǝnʇᴉɐl [%(credential_uuid)s]"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:110
#, python-brace-format
msgid ""
"Provided storage backend ({storage_id}) isn't active. "
@@ -719,64 +744,65 @@ msgstr ""
"Ᵽɹøʌᴉdǝd sʇøɹɐƃǝ bɐɔʞǝnd ({storage_id}) ᴉsn'ʇ ɐɔʇᴉʌǝ. "
"Sʇøɹɐƃǝs: {active_storages}"
-#: apps/verifiable_credentials/rest_api/v1/views.py
+#: credentials/apps/verifiable_credentials/rest_api/v1/views.py:209
#, python-brace-format
msgid "Can't find an Issuer with such ID [{issuer_id}]"
msgstr "Ȼɐn'ʇ ɟᴉnd ɐn Ɨssnǝɹ ʍᴉʇɥ snɔɥ ƗĐ [{issuer_id}]"
-#: apps/verifiable_credentials/storages/learner_credential_wallet.py
+#: credentials/apps/verifiable_credentials/storages/learner_credential_wallet.py:39
msgid "Learner Credential Wallet"
msgstr "Łǝɐɹnǝɹ Ȼɹǝdǝnʇᴉɐl Wɐllǝʇ"
-#: templates/404.html
+#: credentials/templates/404.html:6 credentials/templates/404.html:11
msgid "Page Not Found"
msgstr "Ᵽɐƃǝ Nøʇ Fønnd"
-#: templates/500.html
+#: credentials/templates/500.html:6 credentials/templates/500.html:11
msgid "Server Error"
msgstr "Sǝɹʌǝɹ Ɇɹɹøɹ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:7
msgid "Print or share your certificate"
msgstr "Ᵽɹᴉnʇ øɹ sɥɐɹǝ ʎønɹ ɔǝɹʇᴉɟᴉɔɐʇǝ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:9 credentials/templates/_actions.html:19
msgid "Share this certificate via Facebook"
msgstr "Sɥɐɹǝ ʇɥᴉs ɔǝɹʇᴉɟᴉɔɐʇǝ ʌᴉɐ Fɐɔǝbøøʞ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:24
+#: credentials/templates/_actions.html:32
msgid "Tweet this certificate"
msgstr "Ŧʍǝǝʇ ʇɥᴉs ɔǝɹʇᴉɟᴉɔɐʇǝ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:38
msgid "Add to LinkedIn profile"
msgstr "Ⱥdd ʇø ŁᴉnʞǝdƗn dɹøɟᴉlǝ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:47
msgid "Add this certificate to your LinkedIn profile"
msgstr "Ⱥdd ʇɥᴉs ɔǝɹʇᴉɟᴉɔɐʇǝ ʇø ʎønɹ ŁᴉnʞǝdƗn dɹøɟᴉlǝ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:52
msgid "Print"
msgstr "Ᵽɹᴉnʇ"
-#: templates/_actions.html
+#: credentials/templates/_actions.html:58
msgid "Print this certificate"
msgstr "Ᵽɹᴉnʇ ʇɥᴉs ɔǝɹʇᴉɟᴉɔɐʇǝ"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:7
msgid "Legal Policies"
msgstr "Łǝƃɐl Ᵽølᴉɔᴉǝs"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:11
msgid "Terms of Service & Honor Code"
msgstr "Ŧǝɹɯs øɟ Sǝɹʌᴉɔǝ & Ħønøɹ Ȼødǝ"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:16
msgid "Privacy Policy"
msgstr "Ᵽɹᴉʌɐɔʎ Ᵽølᴉɔʎ"
-#: templates/_footer.html
+#: credentials/templates/_footer.html:26
msgid ""
"All rights reserved except where noted. edX, Open edX and the edX and Open "
"edX logos are registered trademarks or trademarks of edX Inc."
@@ -784,20 +810,21 @@ msgstr ""
"Ⱥll ɹᴉƃɥʇs ɹǝsǝɹʌǝd ǝxɔǝdʇ ʍɥǝɹǝ nøʇǝd. ǝdX, Ødǝn ǝdX ɐnd ʇɥǝ ǝdX ɐnd Ødǝn "
"ǝdX løƃøs ɐɹǝ ɹǝƃᴉsʇǝɹǝd ʇɹɐdǝɯɐɹʞs øɹ ʇɹɐdǝɯɐɹʞs øɟ ǝdX Ɨnɔ."
-#: templates/_footer.html
+#: credentials/templates/_footer.html:36
msgid "Powered by"
msgstr "Ᵽøʍǝɹǝd bʎ"
-#: templates/base.html templates/credentials/base.html
+#: credentials/templates/base.html:42
+#: credentials/templates/credentials/base.html:12
msgid "Skip to main content"
msgstr "Sʞᴉd ʇø ɯɐᴉn ɔønʇǝnʇ"
-#: templates/credentials/base.html
+#: credentials/templates/credentials/base.html:25
#, python-format
msgid "Congratulations, %(user_name)s!"
msgstr "Ȼønƃɹɐʇnlɐʇᴉøns, %(user_name)s!"
-#: templates/credentials/base.html
+#: credentials/templates/credentials/base.html:32
#, python-format
msgid ""
"You worked hard to earn your certificate from %(platform_name)s — share it "
@@ -808,47 +835,45 @@ msgstr ""
"ʍᴉʇɥ ɔøllǝɐƃnǝs, ɟɹᴉǝnds, ɐnd ɟɐɯᴉlʎ ʇø ƃǝʇ ʇɥǝ ʍøɹd ønʇ ɐbønʇ ʍɥɐʇ ʎøn "
"ɯɐsʇǝɹǝd ᴉn %(program_display_name)s."
-#: templates/credentials/edx_ace/common/base_body.html
+#: credentials/templates/credentials/edx_ace/common/base_body.html:33
#, python-format
msgid "Go to %(platform_name)s Home Page"
msgstr "Ǥø ʇø %(platform_name)s Ħøɯǝ Ᵽɐƃǝ"
-#: templates/credentials/edx_ace/common/base_body.html
+#: credentials/templates/credentials/edx_ace/common/base_body.html:58
msgid "All rights reserved"
msgstr "Ⱥll ɹᴉƃɥʇs ɹǝsǝɹʌǝd"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html:11
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:2
msgid "Hello"
msgstr "Ħǝllø"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html:14
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:4
#, python-format
msgid ""
-"Congratulations on completing the %(program_title)s %(program_type)s "
-"Program!"
+"Congratulations on completing the %(program_title)s %(program_type)s Program!"
msgstr ""
-"Ȼønƃɹɐʇnlɐʇᴉøns øn ɔøɯdlǝʇᴉnƃ ʇɥǝ %(program_title)s %(program_type)s "
-"Ᵽɹøƃɹɐɯ!"
+"Ȼønƃɹɐʇnlɐʇᴉøns øn ɔøɯdlǝʇᴉnƃ ʇɥǝ %(program_title)s %(program_type)s Ᵽɹøƃɹɐɯ!"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.html:18
#, python-format
msgid "Sincerely,
The %(platform_name)s Team"
msgstr "Sᴉnɔǝɹǝlʎ,
Ŧɥǝ %(platform_name)s Ŧǝɐɯ"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:6
msgid "Sincerely"
msgstr "Sᴉnɔǝɹǝlʎ"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/body.txt:7
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:23
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:21
#, python-format
msgid "The %(platform_name)s Team"
msgstr "Ŧɥǝ %(platform_name)s Ŧǝɐɯ"
-#: templates/credentials/edx_ace/programcertificateissuedmessage/email/subject.txt
+#: credentials/templates/credentials/edx_ace/programcertificateissuedmessage/email/subject.txt:3
#, python-format
msgid ""
"Congratulations for finishing your %(program_title)s %(program_type)s "
@@ -857,17 +882,16 @@ msgstr ""
"Ȼønƃɹɐʇnlɐʇᴉøns ɟøɹ ɟᴉnᴉsɥᴉnƃ ʎønɹ %(program_title)s %(program_type)s "
"Ᵽɹøƃɹɐɯ!"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:30
msgid "Supported by the following organizations"
msgstr "Snddøɹʇǝd bʎ ʇɥǝ ɟølløʍᴉnƃ øɹƃɐnᴉzɐʇᴉøns"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:39
msgid "logo"
msgstr "løƃø"
-#. Translators: This phrase is followed by a statement of the learner's
-#. achievement. e.g. 'has completed the course'
-#: templates/credentials/programs/base.html
+#. Translators: This phrase is followed by a statement of the learner's achievement. e.g. 'has completed the course'
+#: credentials/templates/credentials/programs/base.html:53
#, python-brace-format
msgid ""
"{start_span}This is to certify that{end_span} {start_strong} {user_name} "
@@ -876,9 +900,8 @@ msgstr ""
"{start_span}Ŧɥᴉs ᴉs ʇø ɔǝɹʇᴉɟʎ ʇɥɐʇ{end_span} {start_strong} {user_name} "
"{end_strong}"
-#. Translators: organization_name is the display name for the provided
-#. organization e.g (e.g., Test Organization).
-#: templates/credentials/programs/base.html
+#. Translators: organization_name is the display name for the provided organization e.g (e.g., Test Organization).
+#: credentials/templates/credentials/programs/base.html:67
#, python-format
msgid ""
"a program offered by %(org_name_string)s, in collaboration with "
@@ -887,58 +910,58 @@ msgstr ""
"ɐ dɹøƃɹɐɯ øɟɟǝɹǝd bʎ %(org_name_string)s, ᴉn ɔøllɐbøɹɐʇᴉøn ʍᴉʇɥ "
"%(platform_name)s."
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:75
msgid "Noted by"
msgstr "Nøʇǝd bʎ"
#. Translators: This phrase appears on certificates to show the issue date
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:109
#, python-brace-format
msgid "Issued {month} {year}"
msgstr "Ɨssnǝd {month} {year}"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:115
msgid "Valid Certificate ID"
msgstr "Vɐlᴉd Ȼǝɹʇᴉɟᴉɔɐʇǝ ƗĐ"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:121
msgid "Effort"
msgstr "Ɇɟɟøɹʇ"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:124
#, python-format
msgid "%(num_hours)s hour"
msgid_plural "%(num_hours)s hours"
msgstr[0] "%(num_hours)s ɥønɹ"
msgstr[1] "%(num_hours)s ɥønɹs"
-#: templates/credentials/programs/base.html
+#: credentials/templates/credentials/programs/base.html:138
#, python-brace-format
msgid ""
-"For tips and tricks on printing your certificate, view the {start_anchor}Web"
-" Certificates help documentation{end_anchor}."
+"For tips and tricks on printing your certificate, view the {start_anchor}Web "
+"Certificates help documentation{end_anchor}."
msgstr ""
-"Føɹ ʇᴉds ɐnd ʇɹᴉɔʞs øn dɹᴉnʇᴉnƃ ʎønɹ ɔǝɹʇᴉɟᴉɔɐʇǝ, ʌᴉǝʍ ʇɥǝ {start_anchor}Wǝb"
-" Ȼǝɹʇᴉɟᴉɔɐʇǝs ɥǝld døɔnɯǝnʇɐʇᴉøn{end_anchor}."
+"Føɹ ʇᴉds ɐnd ʇɹᴉɔʞs øn dɹᴉnʇᴉnƃ ʎønɹ ɔǝɹʇᴉɟᴉɔɐʇǝ, ʌᴉǝʍ ʇɥǝ {start_anchor}Wǝb "
+"Ȼǝɹʇᴉɟᴉɔɐʇǝs ɥǝld døɔnɯǝnʇɐʇᴉøn{end_anchor}."
-#: templates/management.html
+#: credentials/templates/management.html:9
msgid "Management View"
msgstr "Mɐnɐƃǝɯǝnʇ Vᴉǝʍ"
-#: templates/management.html
+#: credentials/templates/management.html:23
msgid "Clear cache"
msgstr "Ȼlǝɐɹ ɔɐɔɥǝ"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:5
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:5
#, python-format
msgid ""
"%(user_full_name)s has sent an updated program record for %(program_name)s."
msgstr ""
"%(user_full_name)s ɥɐs sǝnʇ ɐn nddɐʇǝd dɹøƃɹɐɯ ɹǝɔøɹd ɟøɹ %(program_name)s."
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:7
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:7
#, python-format
msgid ""
"%(user_full_name)s has sent their completed program record for "
@@ -947,8 +970,8 @@ msgstr ""
"%(user_full_name)s ɥɐs sǝnʇ ʇɥǝᴉɹ ɔøɯdlǝʇǝd dɹøƃɹɐɯ ɹǝɔøɹd ɟøɹ "
"%(program_name)s."
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:11
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:11
#, python-format
msgid ""
"%(user_full_name)s has sent their partially completed program record for "
@@ -957,16 +980,16 @@ msgstr ""
"%(user_full_name)s ɥɐs sǝnʇ ʇɥǝᴉɹ dɐɹʇᴉɐllʎ ɔøɯdlǝʇǝd dɹøƃɹɐɯ ɹǝɔøɹd ɟøɹ "
"%(program_name)s."
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:14
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:14
#, python-format
msgid ""
"%(user_full_name)s would like to apply for credit in the %(pathway_name)s."
msgstr ""
"%(user_full_name)s ʍønld lᴉʞǝ ʇø ɐddlʎ ɟøɹ ɔɹǝdᴉʇ ᴉn ʇɥǝ %(pathway_name)s."
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:16
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:16
#, python-format
msgid ""
"Please view or download %(user_full_name)s’s public program record to "
@@ -975,26 +998,26 @@ msgstr ""
"Ᵽlǝɐsǝ ʌᴉǝʍ øɹ døʍnløɐd %(user_full_name)s’s dnblᴉɔ dɹøƃɹɐɯ ɹǝɔøɹd ʇø "
"dǝʇǝɹɯᴉnǝ ʇɥǝᴉɹ ɔɹǝdᴉʇ ǝlᴉƃᴉbᴉlᴉʇʎ sʇɐʇns."
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:19
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:18
msgid "View Program Record"
msgstr "Vᴉǝʍ Ᵽɹøƃɹɐɯ Ɍǝɔøɹd"
-#: templates/records/edx_ace/programcreditrequest/email/body.html
-#: templates/records/edx_ace/programcreditrequest/email/body.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.html:20
+#: credentials/templates/records/edx_ace/programcreditrequest/email/body.txt:19
msgid "Download Record (CSV)"
msgstr "Đøʍnløɐd Ɍǝɔøɹd (ȻSV)"
-#: templates/records/edx_ace/programcreditrequest/email/subject.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/subject.txt:4
#, python-format
msgid "%(program_name)s Updated Credit Request for %(user_full_name)s"
msgstr "%(program_name)s Ʉddɐʇǝd Ȼɹǝdᴉʇ Ɍǝbnǝsʇ ɟøɹ %(user_full_name)s"
-#: templates/records/edx_ace/programcreditrequest/email/subject.txt
+#: credentials/templates/records/edx_ace/programcreditrequest/email/subject.txt:6
#, python-format
msgid "%(program_name)s Credit Request for %(user_full_name)s"
msgstr "%(program_name)s Ȼɹǝdᴉʇ Ɍǝbnǝsʇ ɟøɹ %(user_full_name)s"
-#: urls.py
+#: credentials/urls.py:39
msgid "Credentials Administration"
msgstr "Ȼɹǝdǝnʇᴉɐls Ⱥdɯᴉnᴉsʇɹɐʇᴉøn"